#!/usr/bin/env node
//  ********** Library dart:core **************
//  ********** Natives dart:core **************
function $defProp(obj, prop, value) {
  Object.defineProperty(obj, prop,
      {value: value, enumerable: false, writable: true, configurable: true});
}
Function.prototype.bind = Function.prototype.bind ||
  function(thisObj) {
    var func = this;
    var funcLength = func.$length || func.length;
    var argsLength = arguments.length;
    if (argsLength > 1) {
      var boundArgs = Array.prototype.slice.call(arguments, 1);
      var bound = function() {
        // Prepend the bound arguments to the current arguments.
        var newArgs = Array.prototype.slice.call(arguments);
        Array.prototype.unshift.apply(newArgs, boundArgs);
        return func.apply(thisObj, newArgs);
      };
      bound.$length = Math.max(0, funcLength - (argsLength - 1));
      return bound;
    } else {
      var bound = function() {
        return func.apply(thisObj, arguments);
      };
      bound.$length = funcLength;
      return bound;
    }
  };
function $throw(e) {
  // If e is not a value, we can use V8's captureStackTrace utility method.
  // TODO(jmesserly): capture the stack trace on other JS engines.
  if (e && (typeof e == 'object') && Error.captureStackTrace) {
    // TODO(jmesserly): this will clobber the e.stack property
    Error.captureStackTrace(e, $throw);
  }
  throw e;
}
$defProp(Object.prototype, '$index', function(i) {
  $throw(new NoSuchMethodException(this, "operator []", [i]));
});
$defProp(Array.prototype, '$index', function(index) {
  var i = index | 0;
  if (i !== index) {
    throw new IllegalArgumentException('index is not int');
  } else if (i < 0 || i >= this.length) {
    throw new IndexOutOfRangeException(index);
  }
  return this[i];
});
$defProp(String.prototype, '$index', function(i) {
  return this[i];
});
$defProp(Object.prototype, '$setindex', function(i, value) {
  $throw(new NoSuchMethodException(this, "operator []=", [i, value]));
});
$defProp(Array.prototype, '$setindex', function(index, value) {
  var i = index | 0;
  if (i !== index) {
    throw new IllegalArgumentException('index is not int');
  } else if (i < 0 || i >= this.length) {
    throw new IndexOutOfRangeException(index);
  }
  return this[i] = value;
});
function $add$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'string') {
    var str = (y == null) ? 'null' : y.toString();
    if (typeof(str) != 'string') {
      throw new Error("calling toString() on right hand operand of operator " +
      "+ did not return a String");
    }
    return x + str;
  } else if (typeof(x) == 'object') {
    return x.$add(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator +", [y]));
  }
}

function $add$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x + y;
  return $add$complex$(x, y);
}
function $bit_xor$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$bit_xor(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator ^", [y]));
  }
}
function $bit_xor$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x ^ y;
  return $bit_xor$complex$(x, y);
}
function $eq$(x, y) {
  if (x == null) return y == null;
  return (typeof(x) != 'object') ? x === y : x.$eq(y);
}
// TODO(jimhug): Should this or should it not match equals?
$defProp(Object.prototype, '$eq', function(other) {
  return this === other;
});
function $gt$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$gt(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator >", [y]));
  }
}
function $gt$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x > y;
  return $gt$complex$(x, y);
}
function $gte$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$gte(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator >=", [y]));
  }
}
function $gte$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x >= y;
  return $gte$complex$(x, y);
}
function $lt$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$lt(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator <", [y]));
  }
}
function $lt$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x < y;
  return $lt$complex$(x, y);
}
function $lte$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$lte(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator <=", [y]));
  }
}
function $lte$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x <= y;
  return $lte$complex$(x, y);
}
function $mod$(x, y) {
  if (typeof(x) == 'number') {
    if (typeof(y) == 'number') {
      var result = x % y;
      if (result == 0) {
        return 0;  // Make sure we don't return -0.0.
      } else if (result < 0) {
        if (y < 0) {
          return result - y;
        } else {
          return result + y;
        }
      }
      return result;
    } else {
      $throw(new IllegalArgumentException(y));
    }
  } else if (typeof(x) == 'object') {
    return x.$mod(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator %", [y]));
  }
}
function $mul$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$mul(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator *", [y]));
  }
}
function $mul$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x * y;
  return $mul$complex$(x, y);
}
function $ne$(x, y) {
  if (x == null) return y != null;
  return (typeof(x) != 'object') ? x !== y : !x.$eq(y);
}
function $shl$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$shl(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator <<", [y]));
  }
}
function $shl$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x << y;
  return $shl$complex$(x, y);
}
function $sub$complex$(x, y) {
  if (typeof(x) == 'number') {
    $throw(new IllegalArgumentException(y));
  } else if (typeof(x) == 'object') {
    return x.$sub(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator -", [y]));
  }
}
function $sub$(x, y) {
  if (typeof(x) == 'number' && typeof(y) == 'number') return x - y;
  return $sub$complex$(x, y);
}
function $truncdiv$(x, y) {
  if (typeof(x) == 'number') {
    if (typeof(y) == 'number') {
      if (y == 0) $throw(new IntegerDivisionByZeroException());
      var tmp = x / y;
      return (tmp < 0) ? Math.ceil(tmp) : Math.floor(tmp);
    } else {
      $throw(new IllegalArgumentException(y));
    }
  } else if (typeof(x) == 'object') {
    return x.$truncdiv(y);
  } else {
    $throw(new NoSuchMethodException(x, "operator ~/", [y]));
  }
}
// ********** Code for Object **************
$defProp(Object.prototype, "get$dynamic", function() {
  "use strict"; return this;
});
$defProp(Object.prototype, "noSuchMethod", function(name, args) {
  $throw(new NoSuchMethodException(this, name, args));
});
$defProp(Object.prototype, "_pushBlock$1", function($0) {
  return this.noSuchMethod("_pushBlock", [$0]);
});
$defProp(Object.prototype, "analyze$1", function($0) {
  return this.noSuchMethod("analyze", [$0]);
});
$defProp(Object.prototype, "contains$1", function($0) {
  return this.noSuchMethod("contains", [$0]);
});
$defProp(Object.prototype, "create$3$isFinal", function($0, $1, $2, isFinal) {
  return this.noSuchMethod("create", [$0, $1, $2, isFinal]);
});
$defProp(Object.prototype, "end$0", function() {
  return this.noSuchMethod("end", []);
});
$defProp(Object.prototype, "indexOf$1", function($0) {
  return this.noSuchMethod("indexOf", [$0]);
});
$defProp(Object.prototype, "instanceOf$3$isTrue$forceCheck", function($0, $1, $2, isTrue, forceCheck) {
  return this.noSuchMethod("instanceOf", [$0, $1, $2, isTrue, forceCheck]);
});
$defProp(Object.prototype, "instanceOf$4", function($0, $1, $2, $3) {
  return this.noSuchMethod("instanceOf", [$0, $1, $2, $3]);
});
$defProp(Object.prototype, "invokeNoSuchMethod$3", function($0, $1, $2) {
  return this.noSuchMethod("invokeNoSuchMethod", [$0, $1, $2]);
});
$defProp(Object.prototype, "is$Collection", function() {
  return false;
});
$defProp(Object.prototype, "is$List", function() {
  return false;
});
$defProp(Object.prototype, "is$Map", function() {
  return false;
});
$defProp(Object.prototype, "is$RegExp", function() {
  return false;
});
$defProp(Object.prototype, "remove$1", function($0) {
  return this.noSuchMethod("remove", [$0]);
});
$defProp(Object.prototype, "run$0", function() {
  return this.noSuchMethod("run", []);
});
$defProp(Object.prototype, "setIndex$4$kind", function($0, $1, $2, $3, kind) {
  return this.noSuchMethod("setIndex", [$0, $1, $2, $3, kind]);
});
$defProp(Object.prototype, "setIndex$4$kind$returnKind", function($0, $1, $2, $3, kind, returnKind) {
  return this.noSuchMethod("setIndex", [$0, $1, $2, $3, kind, returnKind]);
});
$defProp(Object.prototype, "set_$4$kind", function($0, $1, $2, $3, kind) {
  return this.noSuchMethod("set_", [$0, $1, $2, $3, kind]);
});
$defProp(Object.prototype, "set_$4$kind$returnKind", function($0, $1, $2, $3, kind, returnKind) {
  return this.noSuchMethod("set_", [$0, $1, $2, $3, kind, returnKind]);
});
$defProp(Object.prototype, "substring$1", function($0) {
  return this.noSuchMethod("substring", [$0]);
});
$defProp(Object.prototype, "toString$0", function() {
  return this.toString();
});
$defProp(Object.prototype, "visitBinaryExpression$1", function($0) {
  return this.noSuchMethod("visitBinaryExpression", [$0]);
});
$defProp(Object.prototype, "visitCallExpression$1", function($0) {
  return this.noSuchMethod("visitCallExpression", [$0]);
});
$defProp(Object.prototype, "visitPostfixExpression$1", function($0) {
  return this.noSuchMethod("visitPostfixExpression", [$0]);
});
$defProp(Object.prototype, "write$1", function($0) {
  return this.noSuchMethod("write", [$0]);
});
// ********** Code for Clock **************
function Clock() {}
Clock.now = function() {
  return new Date().getTime();
}
Clock.frequency = function() {
  return (1000);
}
// ********** Code for IndexOutOfRangeException **************
function IndexOutOfRangeException(_index) {
  this._index = _index;
}
IndexOutOfRangeException.prototype.is$IndexOutOfRangeException = function(){return true};
IndexOutOfRangeException.prototype.toString = function() {
  return ("IndexOutOfRangeException: " + this._index);
}
IndexOutOfRangeException.prototype.toString$0 = IndexOutOfRangeException.prototype.toString;
// ********** Code for IllegalAccessException **************
function IllegalAccessException() {

}
IllegalAccessException.prototype.toString = function() {
  return "Attempt to modify an immutable object";
}
IllegalAccessException.prototype.toString$0 = IllegalAccessException.prototype.toString;
// ********** Code for NoSuchMethodException **************
function NoSuchMethodException(_receiver, _functionName, _arguments, _existingArgumentNames) {
  this._existingArgumentNames = _existingArgumentNames;
  this._receiver = _receiver;
  this._functionName = _functionName;
  this._arguments = _arguments;
}
NoSuchMethodException.prototype.is$NoSuchMethodException = function(){return true};
NoSuchMethodException.prototype.toString = function() {
  var sb = new StringBufferImpl("");
  for (var i = (0);
   i < this._arguments.get$length(); i++) {
    if (i > (0)) {
      sb.add(", ");
    }
    sb.add(this._arguments.$index(i));
  }
  if (null == this._existingArgumentNames) {
    return $add$($add$(("NoSuchMethodException : method not found: '" + this._functionName + "'\n"), ("Receiver: " + this._receiver + "\n")), ("Arguments: [" + sb + "]"));
  }
  else {
    var actualParameters = sb.toString();
    sb = new StringBufferImpl("");
    for (var i = (0);
     i < this._existingArgumentNames.get$length(); i++) {
      if (i > (0)) {
        sb.add(", ");
      }
      sb.add(this._existingArgumentNames.$index(i));
    }
    var formalParameters = sb.toString();
    return $add$($add$($add$("NoSuchMethodException: incorrect number of arguments passed to ", ("method named '" + this._functionName + "'\nReceiver: " + this._receiver + "\n")), ("Tried calling: " + this._functionName + "(" + actualParameters + ")\n")), ("Found: " + this._functionName + "(" + formalParameters + ")"));
  }
}
NoSuchMethodException.prototype.toString$0 = NoSuchMethodException.prototype.toString;
// ********** Code for ClosureArgumentMismatchException **************
function ClosureArgumentMismatchException() {

}
ClosureArgumentMismatchException.prototype.toString = function() {
  return "Closure argument mismatch";
}
ClosureArgumentMismatchException.prototype.toString$0 = ClosureArgumentMismatchException.prototype.toString;
// ********** Code for ObjectNotClosureException **************
function ObjectNotClosureException() {

}
ObjectNotClosureException.prototype.toString = function() {
  return "Object is not closure";
}
ObjectNotClosureException.prototype.toString$0 = ObjectNotClosureException.prototype.toString;
// ********** Code for IllegalArgumentException **************
function IllegalArgumentException(arg) {
  this._arg = arg;
}
IllegalArgumentException.prototype.is$IllegalArgumentException = function(){return true};
IllegalArgumentException.prototype.toString = function() {
  return ("Illegal argument(s): " + this._arg);
}
IllegalArgumentException.prototype.toString$0 = IllegalArgumentException.prototype.toString;
// ********** Code for StackOverflowException **************
function StackOverflowException() {

}
StackOverflowException.prototype.toString = function() {
  return "Stack Overflow";
}
StackOverflowException.prototype.toString$0 = StackOverflowException.prototype.toString;
// ********** Code for BadNumberFormatException **************
function BadNumberFormatException(_s) {
  this._s = _s;
}
BadNumberFormatException.prototype.toString = function() {
  return ("BadNumberFormatException: '" + this._s + "'");
}
BadNumberFormatException.prototype.toString$0 = BadNumberFormatException.prototype.toString;
// ********** Code for NullPointerException **************
function NullPointerException() {

}
NullPointerException.prototype.toString = function() {
  return "NullPointerException";
}
NullPointerException.prototype.toString$0 = NullPointerException.prototype.toString;
// ********** Code for NoMoreElementsException **************
function NoMoreElementsException() {

}
NoMoreElementsException.prototype.toString = function() {
  return "NoMoreElementsException";
}
NoMoreElementsException.prototype.toString$0 = NoMoreElementsException.prototype.toString;
// ********** Code for EmptyQueueException **************
function EmptyQueueException() {

}
EmptyQueueException.prototype.toString = function() {
  return "EmptyQueueException";
}
EmptyQueueException.prototype.toString$0 = EmptyQueueException.prototype.toString;
// ********** Code for IntegerDivisionByZeroException **************
function IntegerDivisionByZeroException() {

}
IntegerDivisionByZeroException.prototype.is$IntegerDivisionByZeroException = function(){return true};
IntegerDivisionByZeroException.prototype.toString = function() {
  return "IntegerDivisionByZeroException";
}
IntegerDivisionByZeroException.prototype.toString$0 = IntegerDivisionByZeroException.prototype.toString;
// ********** Code for dart_core_Function **************
Function.prototype.to$call$0 = function() {
  this.call$0 = this._genStub(0);
  this.to$call$0 = function() { return this.call$0; };
  return this.call$0;
};
Function.prototype.call$0 = function() {
  return this.to$call$0()();
};
function to$call$0(f) { return f && f.to$call$0(); }
Function.prototype.to$call$1 = function() {
  this.call$1 = this._genStub(1);
  this.to$call$1 = function() { return this.call$1; };
  return this.call$1;
};
Function.prototype.call$1 = function($0) {
  return this.to$call$1()($0);
};
function to$call$1(f) { return f && f.to$call$1(); }
Function.prototype.to$call$2 = function() {
  this.call$2 = this._genStub(2);
  this.to$call$2 = function() { return this.call$2; };
  return this.call$2;
};
Function.prototype.call$2 = function($0, $1) {
  return this.to$call$2()($0, $1);
};
function to$call$2(f) { return f && f.to$call$2(); }
// ********** Code for Math **************
Math.parseInt = function(str) {
  var ret = parseInt(str);
    if (isNaN(ret)) $throw(new BadNumberFormatException(str));
    return ret;
}
Math.parseDouble = function(str) {
  var ret = parseFloat(str);
    if (isNaN(ret) && str != 'NaN') $throw(new BadNumberFormatException(str));
    return ret;
}
Math.min = function(a, b) {
  if (a == b) return a;
    if (a < b) {
      if (isNaN(b)) return b;
      else return a;
    }
    if (isNaN(a)) return a;
    else return b;
}
// ********** Code for Strings **************
function Strings() {}
Strings.String$fromCharCodes$factory = function(charCodes) {
  return StringBase.createFromCharCodes(charCodes);
}
Strings.join = function(strings, separator) {
  return StringBase.join(strings, separator);
}
// ********** Code for top level **************
function print$(obj) {
  return _print(obj);
}
function _print(obj) {
  if (typeof console == 'object') {
    if (obj) obj = obj.toString();
    console.log(obj);
  } else if (typeof write === 'function') {
    write(obj);
    write('\n');
  }
}
function _toDartException(e) {
  function attachStack(dartEx) {
    // TODO(jmesserly): setting the stack property is not a long term solution.
    var stack = e.stack;
    // The stack contains the error message, and the stack is all that is
    // printed (the exception's toString() is never called).  Make the Dart
    // exception's toString() be the dominant message.
    if (typeof stack == 'string') {
      var message = dartEx.toString();
      if (/^(Type|Range)Error:/.test(stack)) {
        // Indent JS message (it can be helpful) so new message stands out.
        stack = '    (' + stack.substring(0, stack.indexOf('\n')) + ')\n' +
                stack.substring(stack.indexOf('\n') + 1);
      }
      stack = message + '\n' + stack;
    }
    dartEx.stack = stack;
    return dartEx;
  }

  if (e instanceof TypeError) {
    switch(e.type) {
      case 'property_not_function':
      case 'called_non_callable':
        if (e.arguments[0] == null) {
          return attachStack(new NullPointerException());
        } else {
          return attachStack(new ObjectNotClosureException());
        }
        break;
      case 'non_object_property_call':
      case 'non_object_property_load':
        return attachStack(new NullPointerException());
        break;
      case 'undefined_method':
        var mname = e.arguments[0];
        if (typeof(mname) == 'string' && (mname.indexOf('call$') == 0
            || mname == 'call' || mname == 'apply')) {
          return attachStack(new ObjectNotClosureException());
        } else {
          // TODO(jmesserly): fix noSuchMethod on operators so we don't hit this
          return attachStack(new NoSuchMethodException('', e.arguments[0], []));
        }
        break;
    }
  } else if (e instanceof RangeError) {
    if (e.message.indexOf('call stack') >= 0) {
      return attachStack(new StackOverflowException());
    }
  }
  return e;
}
//  ********** Library dart:coreimpl **************
// ********** Code for ListFactory **************
ListFactory = Array;
$defProp(ListFactory.prototype, "is$List", function(){return true});
$defProp(ListFactory.prototype, "is$Collection", function(){return true});
ListFactory.ListFactory$from$factory = function(other) {
  var list = [];
  for (var $$i = other.iterator(); $$i.hasNext(); ) {
    var e = $$i.next();
    list.add(e);
  }
  return list;
}
$defProp(ListFactory.prototype, "get$length", function() { return this.length; });
$defProp(ListFactory.prototype, "set$length", function(value) { return this.length = value; });
$defProp(ListFactory.prototype, "add", function(value) {
  this.push(value);
});
$defProp(ListFactory.prototype, "addLast", function(value) {
  this.push(value);
});
$defProp(ListFactory.prototype, "addAll", function(collection) {
  for (var $$i = collection.iterator(); $$i.hasNext(); ) {
    var item = $$i.next();
    this.add(item);
  }
});
$defProp(ListFactory.prototype, "clear", function() {
  this.set$length((0));
});
$defProp(ListFactory.prototype, "removeLast", function() {
  return this.pop();
});
$defProp(ListFactory.prototype, "last", function() {
  return this.$index(this.get$length() - (1));
});
$defProp(ListFactory.prototype, "getRange", function(start, length) {
      if (length == 0) return [];
      if (length < 0) throw new IllegalArgumentException('length');
      if (start < 0 || start + length > this.length)
        throw new IndexOutOfRangeException(start);
      return this.slice(start, start + length);
    
});
$defProp(ListFactory.prototype, "insertRange", function(start, length, initialValue) {
      if (length == 0) return;
      if (length < 0) throw new IllegalArgumentException('length');
      if (start < 0 || start > this.length)
        throw new IndexOutOfRangeException(start);

      // Splice in the values with a minimum of array allocations.
      var args = new Array(length + 2);
      args[0] = start;
      args[1] = 0;
      for (var i = 0; i < length; i++) {
        args[i + 2] = initialValue;
      }
      this.splice.apply(this, args);
      
});
$defProp(ListFactory.prototype, "isEmpty", function() {
  return this.get$length() == (0);
});
$defProp(ListFactory.prototype, "iterator", function() {
  return new ListIterator(this);
});
$defProp(ListFactory.prototype, "toString", function() {
  return Collections.collectionToString(this);
});
$defProp(ListFactory.prototype, "indexOf$1", ListFactory.prototype.indexOf);
$defProp(ListFactory.prototype, "toString$0", ListFactory.prototype.toString);
// ********** Code for ListIterator **************
function ListIterator(array) {
  this._array = array;
  this._pos = (0);
}
ListIterator.prototype.hasNext = function() {
  return this._array.get$length() > this._pos;
}
ListIterator.prototype.next = function() {
  if (!this.hasNext()) {
    $throw(const$0001);
  }
  return this._array.$index(this._pos++);
}
// ********** Code for ImmutableList **************
/** Implements extends for Dart classes on JavaScript prototypes. */
function $inherits(child, parent) {
  if (child.prototype.__proto__) {
    child.prototype.__proto__ = parent.prototype;
  } else {
    function tmp() {};
    tmp.prototype = parent.prototype;
    child.prototype = new tmp();
    child.prototype.constructor = child;
  }
}
$inherits(ImmutableList, ListFactory);
function ImmutableList(length) {
  Array.call(this, length);
}
ImmutableList.ImmutableList$from$factory = function(other) {
  return _constList(other);
}
ImmutableList.prototype.get$length = function() {
  return this.length;
}
ImmutableList.prototype.set$length = function(length) {
  $throw(const$0006);
}
ImmutableList.prototype.$setindex = function(index, value) {
  $throw(const$0006);
}
ImmutableList.prototype.insertRange = function(start, length, initialValue) {
  $throw(const$0006);
}
ImmutableList.prototype.sort = function(compare) {
  $throw(const$0006);
}
ImmutableList.prototype.add = function(element) {
  $throw(const$0006);
}
ImmutableList.prototype.addLast = function(element) {
  $throw(const$0006);
}
ImmutableList.prototype.addAll = function(elements) {
  $throw(const$0006);
}
ImmutableList.prototype.clear = function() {
  $throw(const$0006);
}
ImmutableList.prototype.removeLast = function() {
  $throw(const$0006);
}
ImmutableList.prototype.toString = function() {
  return Collections.collectionToString(this);
}
ImmutableList.prototype.toString$0 = ImmutableList.prototype.toString;
// ********** Code for JSSyntaxRegExp **************
function JSSyntaxRegExp(pattern, multiLine, ignoreCase) {
  JSSyntaxRegExp._create$ctor.call(this, pattern, $add$(($eq$(multiLine, true) ? "m" : ""), ($eq$(ignoreCase, true) ? "i" : "")));
}
JSSyntaxRegExp._create$ctor = function(pattern, flags) {
  this.re = new RegExp(pattern, flags);
      this.pattern = pattern;
      this.multiLine = this.re.multiline;
      this.ignoreCase = this.re.ignoreCase;
}
JSSyntaxRegExp._create$ctor.prototype = JSSyntaxRegExp.prototype;
JSSyntaxRegExp.prototype.is$RegExp = function(){return true};
JSSyntaxRegExp.prototype.firstMatch = function(str) {
  var m = this._exec(str);
  return m == null ? null : new MatchImplementation(this.pattern, str, this._matchStart(m), this.get$_lastIndex(), m);
}
JSSyntaxRegExp.prototype._exec = function(str) {
  return this.re.exec(str);
}
JSSyntaxRegExp.prototype._matchStart = function(m) {
  return m.index;
}
JSSyntaxRegExp.prototype.get$_lastIndex = function() {
  return this.re.lastIndex;
}
JSSyntaxRegExp.prototype.hasMatch = function(str) {
  return this.re.test(str);
}
JSSyntaxRegExp.prototype.allMatches = function(str) {
  return new _AllMatchesIterable(this, str);
}
JSSyntaxRegExp.prototype.get$_global = function() {
  return new JSSyntaxRegExp._create$ctor(this.pattern, $add$($add$("g", (this.multiLine ? "m" : "")), (this.ignoreCase ? "i" : "")));
}
// ********** Code for MatchImplementation **************
function MatchImplementation(pattern, str, _start, _end, _groups) {
  this.str = str;
  this._start = _start;
  this._groups = _groups;
  this.pattern = pattern;
  this._end = _end;
}
MatchImplementation.prototype.start = function() {
  return this._start;
}
MatchImplementation.prototype.get$start = function() {
  return this.start.bind(this);
}
MatchImplementation.prototype.end = function() {
  return this._end;
}
MatchImplementation.prototype.$index = function(group) {
  return this._groups.$index(group);
}
MatchImplementation.prototype.end$0 = MatchImplementation.prototype.end;
// ********** Code for _AllMatchesIterable **************
function _AllMatchesIterable(_re, _str) {
  this._re = _re;
  this._str = _str;
}
_AllMatchesIterable.prototype.iterator = function() {
  return new _AllMatchesIterator(this._re, this._str);
}
// ********** Code for _AllMatchesIterator **************
function _AllMatchesIterator(re, _str) {
  this._done = false;
  this._re = re.get$_global();
  this._str = _str;
}
_AllMatchesIterator.prototype.next = function() {
  if (!this.hasNext()) {
    $throw(const$0001);
  }
  var next = this._next;
  this._next = null;
  return next;
}
_AllMatchesIterator.prototype.hasNext = function() {
  if (this._done) {
    return false;
  }
  else if (this._next != null) {
    return true;
  }
  this._next = this._re.firstMatch(this._str);
  if (this._next == null) {
    this._done = true;
    return false;
  }
  else {
    return true;
  }
}
// ********** Code for NumImplementation **************
NumImplementation = Number;
NumImplementation.prototype.$negate = function() {
  'use strict'; return -this;
}
NumImplementation.prototype.isNaN = function() {
  'use strict'; return isNaN(this);
}
NumImplementation.prototype.isNegative = function() {
  'use strict'; return this == 0 ? (1 / this) < 0 : this < 0;
}
NumImplementation.prototype.hashCode = function() {
  'use strict'; return this & 0x1FFFFFFF;
}
NumImplementation.prototype.toDouble = function() {
  'use strict'; return this + 0;
}
NumImplementation.prototype.toRadixString = function(radix) {
  'use strict'; return this.toString(radix)
}
NumImplementation.prototype.compareTo = function(other) {
  var thisValue = this.toDouble();
  if (thisValue < other) {
    return (-1);
  }
  else if (thisValue > other) {
    return (1);
  }
  else if (thisValue == other) {
    if (thisValue == (0)) {
      var thisIsNegative = this.isNegative();
      var otherIsNegative = other.isNegative();
      if ($eq$(thisIsNegative, otherIsNegative)) return (0);
      if (thisIsNegative) return (-1);
      return (1);
    }
    return (0);
  }
  else if (this.isNaN()) {
    if (other.isNaN()) {
      return (0);
    }
    return (1);
  }
  else {
    return (-1);
  }
}
// ********** Code for Collections **************
function Collections() {}
Collections.collectionToString = function(c) {
  var result = new StringBufferImpl("");
  Collections._emitCollection(c, result, new Array());
  return result.toString$0();
}
Collections._emitCollection = function(c, result, visiting) {
  visiting.add(c);
  var isList = !!(c && c.is$List());
  result.add(isList ? "[" : "{");
  var first = true;
  for (var $$i = c.iterator(); $$i.hasNext(); ) {
    var e = $$i.next();
    if (!first) {
      result.add(", ");
    }
    first = false;
    Collections._emitObject(e, result, visiting);
  }
  result.add(isList ? "]" : "}");
  visiting.removeLast();
}
Collections._emitObject = function(o, result, visiting) {
  if (!!(o && o.is$Collection())) {
    if (Collections._containsRef(visiting, o)) {
      result.add(!!(o && o.is$List()) ? "[...]" : "{...}");
    }
    else {
      Collections._emitCollection(o, result, visiting);
    }
  }
  else if (!!(o && o.is$Map())) {
    if (Collections._containsRef(visiting, o)) {
      result.add("{...}");
    }
    else {
      Maps._emitMap(o, result, visiting);
    }
  }
  else {
    result.add($eq$(o) ? "null" : o);
  }
}
Collections._containsRef = function(c, ref) {
  for (var $$i = c.iterator(); $$i.hasNext(); ) {
    var e = $$i.next();
    if ((null == e ? null == (ref) : e === ref)) return true;
  }
  return false;
}
// ********** Code for HashMapImplementation **************
function HashMapImplementation() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation.prototype.is$Map = function(){return true};
HashMapImplementation.HashMapImplementation$from$factory = function(other) {
  var result = new HashMapImplementation();
  other.forEach((function (key, value) {
    result.$setindex(key, value);
  })
  );
  return result;
}
HashMapImplementation._computeLoadLimit = function(capacity) {
  return $truncdiv$((capacity * (3)), (4));
}
HashMapImplementation._firstProbe = function(hashCode, length) {
  return hashCode & (length - (1));
}
HashMapImplementation._nextProbe = function(currentProbe, numberOfProbes, length) {
  return (currentProbe + numberOfProbes) & (length - (1));
}
HashMapImplementation.prototype._probeForAdding = function(key) {
  var hash = HashMapImplementation._firstProbe(key.hashCode(), this._keys.get$length());
  var numberOfProbes = (1);
  var initialHash = hash;
  var insertionIndex = (-1);
  while (true) {
    var existingKey = this._keys.$index(hash);
    if (null == existingKey) {
      if (insertionIndex < (0)) return hash;
      return insertionIndex;
    }
    else if ($eq$(existingKey, key)) {
      return hash;
    }
    else if ((insertionIndex < (0)) && ((null == const$0000 ? null == (existingKey) : const$0000 === existingKey))) {
      insertionIndex = hash;
    }
    hash = HashMapImplementation._nextProbe(hash, numberOfProbes++, this._keys.get$length());
  }
}
HashMapImplementation.prototype._probeForLookup = function(key) {
  var hash = HashMapImplementation._firstProbe(key.hashCode(), this._keys.get$length());
  var numberOfProbes = (1);
  var initialHash = hash;
  while (true) {
    var existingKey = this._keys.$index(hash);
    if (null == existingKey) return (-1);
    if ($eq$(existingKey, key)) return hash;
    hash = HashMapImplementation._nextProbe(hash, numberOfProbes++, this._keys.get$length());
  }
}
HashMapImplementation.prototype._ensureCapacity = function() {
  var newNumberOfEntries = this._numberOfEntries + (1);
  if (newNumberOfEntries >= this._loadLimit) {
    this._grow(this._keys.get$length() * (2));
    return;
  }
  var capacity = this._keys.get$length();
  var numberOfFreeOrDeleted = capacity - newNumberOfEntries;
  var numberOfFree = numberOfFreeOrDeleted - this._numberOfDeleted;
  if (this._numberOfDeleted > numberOfFree) {
    this._grow(this._keys.get$length());
  }
}
HashMapImplementation._isPowerOfTwo = function(x) {
  return ((x & (x - (1))) == (0));
}
HashMapImplementation.prototype._grow = function(newCapacity) {
  var capacity = this._keys.get$length();
  this._loadLimit = HashMapImplementation._computeLoadLimit(newCapacity);
  var oldKeys = this._keys;
  var oldValues = this._values;
  this._keys = new Array(newCapacity);
  this._values = new Array(newCapacity);
  for (var i = (0);
   i < capacity; i++) {
    var key = oldKeys.$index(i);
    if (null == key || (null == key ? null == (const$0000) : key === const$0000)) {
      continue;
    }
    var value = oldValues.$index(i);
    var newIndex = this._probeForAdding(key);
    this._keys.$setindex(newIndex, key);
    this._values.$setindex(newIndex, value);
  }
  this._numberOfDeleted = (0);
}
HashMapImplementation.prototype.$setindex = function(key, value) {
  var $0;
  this._ensureCapacity();
  var index = this._probeForAdding(key);
  if ((null == this._keys.$index(index)) || ((($0 = this._keys.$index(index)) == null ? null == (const$0000) : $0 === const$0000))) {
    this._numberOfEntries++;
  }
  this._keys.$setindex(index, key);
  this._values.$setindex(index, value);
}
HashMapImplementation.prototype.$index = function(key) {
  var index = this._probeForLookup(key);
  if (index < (0)) return null;
  return this._values.$index(index);
}
HashMapImplementation.prototype.putIfAbsent = function(key, ifAbsent) {
  var index = this._probeForLookup(key);
  if (index >= (0)) return this._values.$index(index);
  var value = ifAbsent();
  this.$setindex(key, value);
  return value;
}
HashMapImplementation.prototype.remove = function(key) {
  var index = this._probeForLookup(key);
  if (index >= (0)) {
    this._numberOfEntries--;
    var value = this._values.$index(index);
    this._values.$setindex(index);
    this._keys.$setindex(index, const$0000);
    this._numberOfDeleted++;
    return value;
  }
  return null;
}
HashMapImplementation.prototype.isEmpty = function() {
  return this._numberOfEntries == (0);
}
HashMapImplementation.prototype.get$length = function() {
  return this._numberOfEntries;
}
HashMapImplementation.prototype.forEach = function(f) {
  var length = this._keys.get$length();
  for (var i = (0);
   i < length; i++) {
    var key = this._keys.$index(i);
    if ((null != key) && ((null == key ? null != (const$0000) : key !== const$0000))) {
      f(key, this._values.$index(i));
    }
  }
}
HashMapImplementation.prototype.getKeys = function() {
  var list = new Array(this.get$length());
  var i = (0);
  this.forEach(function _(key, value) {
    list.$setindex(i++, key);
  }
  );
  return list;
}
HashMapImplementation.prototype.getValues = function() {
  var list = new Array(this.get$length());
  var i = (0);
  this.forEach(function _(key, value) {
    list.$setindex(i++, value);
  }
  );
  return list;
}
HashMapImplementation.prototype.containsKey = function(key) {
  return (this._probeForLookup(key) != (-1));
}
HashMapImplementation.prototype.toString = function() {
  return Maps.mapToString(this);
}
HashMapImplementation.prototype.remove$1 = HashMapImplementation.prototype.remove;
HashMapImplementation.prototype.toString$0 = HashMapImplementation.prototype.toString;
// ********** Code for HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair **************
$inherits(HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair, HashMapImplementation);
function HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair.prototype.is$Map = function(){return true};
HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair.prototype.remove$1 = HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair.prototype.remove;
// ********** Code for HashMapImplementation_dart_core_String$dart_core_String **************
$inherits(HashMapImplementation_dart_core_String$dart_core_String, HashMapImplementation);
function HashMapImplementation_dart_core_String$dart_core_String() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation_dart_core_String$dart_core_String.prototype.is$Map = function(){return true};
HashMapImplementation_dart_core_String$dart_core_String.prototype.remove$1 = HashMapImplementation_dart_core_String$dart_core_String.prototype.remove;
// ********** Code for HashMapImplementation_dart_core_String$VariableValue **************
$inherits(HashMapImplementation_dart_core_String$VariableValue, HashMapImplementation);
function HashMapImplementation_dart_core_String$VariableValue() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation_dart_core_String$VariableValue.prototype.is$Map = function(){return true};
HashMapImplementation_dart_core_String$VariableValue.prototype.remove$1 = HashMapImplementation_dart_core_String$VariableValue.prototype.remove;
// ********** Code for HashMapImplementation_Library$Library **************
$inherits(HashMapImplementation_Library$Library, HashMapImplementation);
function HashMapImplementation_Library$Library() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation_Library$Library.prototype.is$Map = function(){return true};
// ********** Code for HashMapImplementation_Member$Member **************
$inherits(HashMapImplementation_Member$Member, HashMapImplementation);
function HashMapImplementation_Member$Member() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation_Member$Member.prototype.is$Map = function(){return true};
// ********** Code for HashMapImplementation_Type$Type **************
$inherits(HashMapImplementation_Type$Type, HashMapImplementation);
function HashMapImplementation_Type$Type() {
  this._numberOfEntries = (0);
  this._numberOfDeleted = (0);
  this._loadLimit = HashMapImplementation._computeLoadLimit((8));
  this._keys = new Array((8));
  this._values = new Array((8));
}
HashMapImplementation_Type$Type.prototype.is$Map = function(){return true};
// ********** Code for HashSetImplementation **************
function HashSetImplementation() {
  this._backingMap = new HashMapImplementation();
}
HashSetImplementation.prototype.is$Collection = function(){return true};
HashSetImplementation.HashSetImplementation$from$factory = function(other) {
  var set = new HashSetImplementation();
  for (var $$i = other.iterator(); $$i.hasNext(); ) {
    var e = $$i.next();
    set.add(e);
  }
  return set;
}
HashSetImplementation.prototype.add = function(value) {
  this._backingMap.$setindex(value, value);
}
HashSetImplementation.prototype.contains = function(value) {
  return this._backingMap.containsKey(value);
}
HashSetImplementation.prototype.remove = function(value) {
  if (!this._backingMap.containsKey(value)) return false;
  this._backingMap.remove(value);
  return true;
}
HashSetImplementation.prototype.addAll = function(collection) {
  var $this = this; // closure support
  collection.forEach(function _(value) {
    $this.add(value);
  }
  );
}
HashSetImplementation.prototype.forEach = function(f) {
  this._backingMap.forEach(function _(key, value) {
    f(key);
  }
  );
}
HashSetImplementation.prototype.map = function(f) {
  var result = new HashSetImplementation();
  this._backingMap.forEach(function _(key, value) {
    result.add(f(key));
  }
  );
  return result;
}
HashSetImplementation.prototype.filter = function(f) {
  var result = new HashSetImplementation();
  this._backingMap.forEach(function _(key, value) {
    if (f(key)) result.add(key);
  }
  );
  return result;
}
HashSetImplementation.prototype.every = function(f) {
  var keys = this._backingMap.getKeys();
  return keys.every(f);
}
HashSetImplementation.prototype.some = function(f) {
  var keys = this._backingMap.getKeys();
  return keys.some(f);
}
HashSetImplementation.prototype.isEmpty = function() {
  return this._backingMap.isEmpty();
}
HashSetImplementation.prototype.get$length = function() {
  return this._backingMap.get$length();
}
HashSetImplementation.prototype.iterator = function() {
  return new HashSetIterator(this);
}
HashSetImplementation.prototype.toString = function() {
  return Collections.collectionToString(this);
}
HashSetImplementation.prototype.contains$1 = HashSetImplementation.prototype.contains;
HashSetImplementation.prototype.remove$1 = HashSetImplementation.prototype.remove;
HashSetImplementation.prototype.toString$0 = HashSetImplementation.prototype.toString;
// ********** Code for HashSetImplementation_dart_core_String **************
$inherits(HashSetImplementation_dart_core_String, HashSetImplementation);
function HashSetImplementation_dart_core_String() {
  this._backingMap = new HashMapImplementation_dart_core_String$dart_core_String();
}
HashSetImplementation_dart_core_String.prototype.is$Collection = function(){return true};
HashSetImplementation_dart_core_String.prototype.contains$1 = HashSetImplementation_dart_core_String.prototype.contains;
// ********** Code for HashSetImplementation_Library **************
$inherits(HashSetImplementation_Library, HashSetImplementation);
function HashSetImplementation_Library() {
  this._backingMap = new HashMapImplementation_Library$Library();
}
HashSetImplementation_Library.prototype.is$Collection = function(){return true};
// ********** Code for HashSetImplementation_Member **************
$inherits(HashSetImplementation_Member, HashSetImplementation);
function HashSetImplementation_Member() {
  this._backingMap = new HashMapImplementation_Member$Member();
}
HashSetImplementation_Member.prototype.is$Collection = function(){return true};
// ********** Code for HashSetImplementation_Type **************
$inherits(HashSetImplementation_Type, HashSetImplementation);
function HashSetImplementation_Type() {
  this._backingMap = new HashMapImplementation_Type$Type();
}
HashSetImplementation_Type.prototype.is$Collection = function(){return true};
HashSetImplementation_Type.prototype.contains$1 = HashSetImplementation_Type.prototype.contains;
// ********** Code for HashSetIterator **************
function HashSetIterator(set_) {
  this._entries = set_._backingMap._keys;
  this._nextValidIndex = (-1);
  this._advance();
}
HashSetIterator.prototype.hasNext = function() {
  var $0;
  if (this._nextValidIndex >= this._entries.get$length()) return false;
  if ((($0 = this._entries.$index(this._nextValidIndex)) == null ? null == (const$0000) : $0 === const$0000)) {
    this._advance();
  }
  return this._nextValidIndex < this._entries.get$length();
}
HashSetIterator.prototype.next = function() {
  if (!this.hasNext()) {
    $throw(const$0001);
  }
  var res = this._entries.$index(this._nextValidIndex);
  this._advance();
  return res;
}
HashSetIterator.prototype._advance = function() {
  var length = this._entries.get$length();
  var entry;
  var deletedKey = const$0000;
  do {
    if (++this._nextValidIndex >= length) break;
    entry = this._entries.$index(this._nextValidIndex);
  }
  while ((null == entry) || ((null == entry ? null == (deletedKey) : entry === deletedKey)))
}
// ********** Code for _DeletedKeySentinel **************
function _DeletedKeySentinel() {

}
// ********** Code for KeyValuePair **************
function KeyValuePair(key, value) {
  this.value = value;
  this.key = key;
}
KeyValuePair.prototype.get$value = function() { return this.value; };
KeyValuePair.prototype.set$value = function(value) { return this.value = value; };
// ********** Code for LinkedHashMapImplementation **************
function LinkedHashMapImplementation() {
  this._map = new HashMapImplementation_Dynamic$DoubleLinkedQueueEntry_KeyValuePair();
  this._list = new DoubleLinkedQueue_KeyValuePair();
}
LinkedHashMapImplementation.prototype.is$Map = function(){return true};
LinkedHashMapImplementation.prototype.$setindex = function(key, value) {
  if (this._map.containsKey(key)) {
    this._map.$index(key).get$element().set$value(value);
  }
  else {
    this._list.addLast(new KeyValuePair(key, value));
    this._map.$setindex(key, this._list.lastEntry());
  }
}
LinkedHashMapImplementation.prototype.$index = function(key) {
  var entry = this._map.$index(key);
  if (null == entry) return null;
  return entry.get$element().get$value();
}
LinkedHashMapImplementation.prototype.remove = function(key) {
  var entry = this._map.remove(key);
  if (null == entry) return null;
  entry.remove();
  return entry.get$element().get$value();
}
LinkedHashMapImplementation.prototype.putIfAbsent = function(key, ifAbsent) {
  var value = this.$index(key);
  if ((null == this.$index(key)) && !(this.containsKey(key))) {
    value = ifAbsent();
    this.$setindex(key, value);
  }
  return value;
}
LinkedHashMapImplementation.prototype.getKeys = function() {
  var list = new Array(this.get$length());
  var index = (0);
  this._list.forEach(function _(entry) {
    list.$setindex(index++, entry.key);
  }
  );
  return list;
}
LinkedHashMapImplementation.prototype.getValues = function() {
  var list = new Array(this.get$length());
  var index = (0);
  this._list.forEach(function _(entry) {
    list.$setindex(index++, entry.value);
  }
  );
  return list;
}
LinkedHashMapImplementation.prototype.forEach = function(f) {
  this._list.forEach(function _(entry) {
    f(entry.key, entry.value);
  }
  );
}
LinkedHashMapImplementation.prototype.containsKey = function(key) {
  return this._map.containsKey(key);
}
LinkedHashMapImplementation.prototype.get$length = function() {
  return this._map.get$length();
}
LinkedHashMapImplementation.prototype.isEmpty = function() {
  return this.get$length() == (0);
}
LinkedHashMapImplementation.prototype.toString = function() {
  return Maps.mapToString(this);
}
LinkedHashMapImplementation.prototype.remove$1 = LinkedHashMapImplementation.prototype.remove;
LinkedHashMapImplementation.prototype.toString$0 = LinkedHashMapImplementation.prototype.toString;
// ********** Code for Maps **************
function Maps() {}
Maps.mapToString = function(m) {
  var result = new StringBufferImpl("");
  Maps._emitMap(m, result, new Array());
  return result.toString$0();
}
Maps._emitMap = function(m, result, visiting) {
  visiting.add(m);
  result.add("{");
  var first = true;
  m.forEach((function (k, v) {
    if (!first) {
      result.add(", ");
    }
    first = false;
    Collections._emitObject(k, result, visiting);
    result.add(": ");
    Collections._emitObject(v, result, visiting);
  })
  );
  result.add("}");
  visiting.removeLast();
}
// ********** Code for DoubleLinkedQueueEntry **************
function DoubleLinkedQueueEntry(e) {
  this._element = e;
}
DoubleLinkedQueueEntry.prototype._link = function(p, n) {
  this._next = n;
  this._previous = p;
  p._next = this;
  n._previous = this;
}
DoubleLinkedQueueEntry.prototype.prepend = function(e) {
  new DoubleLinkedQueueEntry(e)._link(this._previous, this);
}
DoubleLinkedQueueEntry.prototype.remove = function() {
  this._previous._next = this._next;
  this._next._previous = this._previous;
  this._next = null;
  this._previous = null;
  return this._element;
}
DoubleLinkedQueueEntry.prototype._asNonSentinelEntry = function() {
  return this;
}
DoubleLinkedQueueEntry.prototype.previousEntry = function() {
  return this._previous._asNonSentinelEntry();
}
DoubleLinkedQueueEntry.prototype.get$element = function() {
  return this._element;
}
// ********** Code for DoubleLinkedQueueEntry_KeyValuePair **************
$inherits(DoubleLinkedQueueEntry_KeyValuePair, DoubleLinkedQueueEntry);
function DoubleLinkedQueueEntry_KeyValuePair(e) {
  this._element = e;
}
// ********** Code for _DoubleLinkedQueueEntrySentinel **************
$inherits(_DoubleLinkedQueueEntrySentinel, DoubleLinkedQueueEntry);
function _DoubleLinkedQueueEntrySentinel() {
  DoubleLinkedQueueEntry.call(this, null);
  this._link(this, this);
}
_DoubleLinkedQueueEntrySentinel.prototype.remove = function() {
  $throw(const$0002);
}
_DoubleLinkedQueueEntrySentinel.prototype._asNonSentinelEntry = function() {
  return null;
}
_DoubleLinkedQueueEntrySentinel.prototype.get$element = function() {
  $throw(const$0002);
}
// ********** Code for _DoubleLinkedQueueEntrySentinel_KeyValuePair **************
$inherits(_DoubleLinkedQueueEntrySentinel_KeyValuePair, _DoubleLinkedQueueEntrySentinel);
function _DoubleLinkedQueueEntrySentinel_KeyValuePair() {
  DoubleLinkedQueueEntry_KeyValuePair.call(this, null);
  this._link(this, this);
}
// ********** Code for DoubleLinkedQueue **************
function DoubleLinkedQueue() {
  this._sentinel = new _DoubleLinkedQueueEntrySentinel();
}
DoubleLinkedQueue.prototype.is$Collection = function(){return true};
DoubleLinkedQueue.DoubleLinkedQueue$from$factory = function(other) {
  var list = new DoubleLinkedQueue();
  for (var $$i = other.iterator(); $$i.hasNext(); ) {
    var e = $$i.next();
    list.addLast(e);
  }
  return list;
}
DoubleLinkedQueue.prototype.addLast = function(value) {
  this._sentinel.prepend(value);
}
DoubleLinkedQueue.prototype.add = function(value) {
  this.addLast(value);
}
DoubleLinkedQueue.prototype.addAll = function(collection) {
  for (var $$i = collection.iterator(); $$i.hasNext(); ) {
    var e = $$i.next();
    this.add(e);
  }
}
DoubleLinkedQueue.prototype.removeLast = function() {
  return this._sentinel._previous.remove();
}
DoubleLinkedQueue.prototype.removeFirst = function() {
  return this._sentinel._next.remove();
}
DoubleLinkedQueue.prototype.last = function() {
  return this._sentinel._previous.get$element();
}
DoubleLinkedQueue.prototype.lastEntry = function() {
  return this._sentinel.previousEntry();
}
DoubleLinkedQueue.prototype.get$length = function() {
  var counter = (0);
  this.forEach(function _(element) {
    counter++;
  }
  );
  return counter;
}
DoubleLinkedQueue.prototype.isEmpty = function() {
  var $0;
  return ((($0 = this._sentinel._next) == null ? null == (this._sentinel) : $0 === this._sentinel));
}
DoubleLinkedQueue.prototype.forEach = function(f) {
  var entry = this._sentinel._next;
  while ((null == entry ? null != (this._sentinel) : entry !== this._sentinel)) {
    var nextEntry = entry._next;
    f(entry._element);
    entry = nextEntry;
  }
}
DoubleLinkedQueue.prototype.every = function(f) {
  var entry = this._sentinel._next;
  while ((null == entry ? null != (this._sentinel) : entry !== this._sentinel)) {
    var nextEntry = entry._next;
    if (!f(entry._element)) return false;
    entry = nextEntry;
  }
  return true;
}
DoubleLinkedQueue.prototype.some = function(f) {
  var entry = this._sentinel._next;
  while ((null == entry ? null != (this._sentinel) : entry !== this._sentinel)) {
    var nextEntry = entry._next;
    if (f(entry._element)) return true;
    entry = nextEntry;
  }
  return false;
}
DoubleLinkedQueue.prototype.map = function(f) {
  var other = new DoubleLinkedQueue();
  var entry = this._sentinel._next;
  while ((null == entry ? null != (this._sentinel) : entry !== this._sentinel)) {
    var nextEntry = entry._next;
    other.addLast(f(entry._element));
    entry = nextEntry;
  }
  return other;
}
DoubleLinkedQueue.prototype.filter = function(f) {
  var other = new DoubleLinkedQueue();
  var entry = this._sentinel._next;
  while ((null == entry ? null != (this._sentinel) : entry !== this._sentinel)) {
    var nextEntry = entry._next;
    if (f(entry._element)) other.addLast(entry._element);
    entry = nextEntry;
  }
  return other;
}
DoubleLinkedQueue.prototype.iterator = function() {
  return new _DoubleLinkedQueueIterator(this._sentinel);
}
DoubleLinkedQueue.prototype.toString = function() {
  return Collections.collectionToString(this);
}
DoubleLinkedQueue.prototype.toString$0 = DoubleLinkedQueue.prototype.toString;
// ********** Code for DoubleLinkedQueue_KeyValuePair **************
$inherits(DoubleLinkedQueue_KeyValuePair, DoubleLinkedQueue);
function DoubleLinkedQueue_KeyValuePair() {
  this._sentinel = new _DoubleLinkedQueueEntrySentinel_KeyValuePair();
}
DoubleLinkedQueue_KeyValuePair.prototype.is$Collection = function(){return true};
// ********** Code for _DoubleLinkedQueueIterator **************
function _DoubleLinkedQueueIterator(_sentinel) {
  this._sentinel = _sentinel;
  this._currentEntry = this._sentinel;
}
_DoubleLinkedQueueIterator.prototype.hasNext = function() {
  var $0;
  return (($0 = this._currentEntry._next) == null ? null != (this._sentinel) : $0 !== this._sentinel);
}
_DoubleLinkedQueueIterator.prototype.next = function() {
  if (!this.hasNext()) {
    $throw(const$0001);
  }
  this._currentEntry = this._currentEntry._next;
  return this._currentEntry.get$element();
}
// ********** Code for StopwatchImplementation **************
function StopwatchImplementation() {
  this._start = null;
  this._stop = null;
}
StopwatchImplementation.prototype.start = function() {
  if (null == this._start) {
    this._start = Clock.now();
  }
  else {
    if (null == this._stop) {
      return;
    }
    this._start = Clock.now() - (this._stop - this._start);
    this._stop = null;
  }
}
StopwatchImplementation.prototype.get$start = function() {
  return this.start.bind(this);
}
StopwatchImplementation.prototype.stop = function() {
  if (null == this._start || null != this._stop) {
    return;
  }
  this._stop = Clock.now();
}
StopwatchImplementation.prototype.elapsed = function() {
  if (null == this._start) {
    return (0);
  }
  return (null == this._stop) ? (Clock.now() - this._start) : (this._stop - this._start);
}
StopwatchImplementation.prototype.elapsedInMs = function() {
  return $truncdiv$((this.elapsed() * (1000)), this.frequency());
}
StopwatchImplementation.prototype.frequency = function() {
  return Clock.frequency();
}
// ********** Code for StringBufferImpl **************
function StringBufferImpl(content) {
  this.clear();
  this.add(content);
}
StringBufferImpl.prototype.get$length = function() {
  return this._length;
}
StringBufferImpl.prototype.isEmpty = function() {
  return this._length == (0);
}
StringBufferImpl.prototype.add = function(obj) {
  var str = obj.toString$0();
  if (null == str || str.isEmpty()) return this;
  this._buffer.add(str);
  this._length = this._length + str.length;
  return this;
}
StringBufferImpl.prototype.addAll = function(objects) {
  for (var $$i = objects.iterator(); $$i.hasNext(); ) {
    var obj = $$i.next();
    this.add(obj);
  }
  return this;
}
StringBufferImpl.prototype.clear = function() {
  this._buffer = new Array();
  this._length = (0);
  return this;
}
StringBufferImpl.prototype.toString = function() {
  if (this._buffer.get$length() == (0)) return "";
  if (this._buffer.get$length() == (1)) return this._buffer.$index((0));
  var result = StringBase.concatAll(this._buffer);
  this._buffer.clear();
  this._buffer.add(result);
  return result;
}
StringBufferImpl.prototype.toString$0 = StringBufferImpl.prototype.toString;
// ********** Code for StringBase **************
function StringBase() {}
StringBase.createFromCharCodes = function(charCodes) {
  if (Object.getPrototypeOf(charCodes) !== Array.prototype) {
    charCodes = new ListFactory.ListFactory$from$factory(charCodes);
  }
  return String.fromCharCode.apply(null, charCodes);
}
StringBase.join = function(strings, separator) {
  if (strings.get$length() == (0)) return "";
  var s = strings.$index((0));
  for (var i = (1);
   i < strings.get$length(); i++) {
    s = $add$($add$(s, separator), strings.$index(i));
  }
  return s;
}
StringBase.concatAll = function(strings) {
  return StringBase.join(strings, "");
}
// ********** Code for StringImplementation **************
StringImplementation = String;
StringImplementation.prototype.get$length = function() { return this.length; };
StringImplementation.prototype.endsWith = function(other) {
    'use strict';
    if (other.length > this.length) return false;
    return other == this.substring(this.length - other.length);
}
StringImplementation.prototype.startsWith = function(other) {
    'use strict';
    if (other.length > this.length) return false;
    return other == this.substring(0, other.length);
}
StringImplementation.prototype.isEmpty = function() {
  return this.length == (0);
}
StringImplementation.prototype.contains = function(pattern, startIndex) {
  'use strict'; return this.indexOf(pattern, startIndex) >= 0;
}
StringImplementation.prototype._replaceRegExp = function(from, to) {
  'use strict';return this.replace(from.re, to);
}
StringImplementation.prototype._replaceAll = function(from, to) {
  'use strict';
  from = new RegExp(from.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), 'g');
  to = to.replace(/\$/g, '$$$$'); // Escape sequences are fun!
  return this.replace(from, to);
}
StringImplementation.prototype.replaceAll = function(from, to) {
  if ((typeof(from) == 'string')) return this._replaceAll(from, to);
  if (!!(from && from.is$RegExp())) return this._replaceRegExp(from.get$dynamic().get$_global(), to);
  var buffer = new StringBufferImpl("");
  var lastMatchEnd = (0);
  var $$list = from.allMatches(this);
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var match = $$i.next();
    buffer.add(this.substring(lastMatchEnd, match.start()));
    buffer.add(to);
    lastMatchEnd = match.end$0();
  }
  buffer.add(this.substring(lastMatchEnd));
}
StringImplementation.prototype.split_ = function(pattern) {
  if ((typeof(pattern) == 'string')) return this._split(pattern);
  if (!!(pattern && pattern.is$RegExp())) return this._splitRegExp(pattern);
  $throw("String.split(Pattern) unimplemented.");
}
StringImplementation.prototype._split = function(pattern) {
  'use strict'; return this.split(pattern);
}
StringImplementation.prototype._splitRegExp = function(pattern) {
  'use strict'; return this.split(pattern.re);
}
StringImplementation.prototype.hashCode = function() {
      'use strict';
      var hash = 0;
      for (var i = 0; i < this.length; i++) {
        hash = 0x1fffffff & (hash + this.charCodeAt(i));
        hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
        hash ^= hash >> 6;
      }

      hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
      hash ^= hash >> 11;
      return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
}
StringImplementation.prototype.compareTo = function(other) {
  'use strict'; return this == other ? 0 : this < other ? -1 : 1;
}
StringImplementation.prototype.contains$1 = StringImplementation.prototype.contains;
StringImplementation.prototype.indexOf$1 = StringImplementation.prototype.indexOf;
StringImplementation.prototype.substring$1 = StringImplementation.prototype.substring;
// ********** Code for _ArgumentMismatchException **************
$inherits(_ArgumentMismatchException, ClosureArgumentMismatchException);
function _ArgumentMismatchException(_message) {
  this._dart_coreimpl_message = _message;
  ClosureArgumentMismatchException.call(this);
}
_ArgumentMismatchException.prototype.toString = function() {
  return ("Closure argument mismatch: " + this._dart_coreimpl_message);
}
_ArgumentMismatchException.prototype.toString$0 = _ArgumentMismatchException.prototype.toString;
// ********** Code for _FunctionImplementation **************
_FunctionImplementation = Function;
_FunctionImplementation.prototype._genStub = function(argsLength, names) {
      // Fast path #1: if no named arguments and arg count matches.
      var thisLength = this.$length || this.length;
      if (thisLength == argsLength && !names) {
        return this;
      }

      var paramsNamed = this.$optional ? (this.$optional.length / 2) : 0;
      var paramsBare = thisLength - paramsNamed;
      var argsNamed = names ? names.length : 0;
      var argsBare = argsLength - argsNamed;

      // Check we got the right number of arguments
      if (argsBare < paramsBare || argsLength > thisLength ||
          argsNamed > paramsNamed) {
        return function() {
          $throw(new _ArgumentMismatchException(
            'Wrong number of arguments to function. Expected ' + paramsBare +
            ' positional arguments and at most ' + paramsNamed +
            ' named arguments, but got ' + argsBare +
            ' positional arguments and ' + argsNamed + ' named arguments.'));
        };
      }

      // First, fill in all of the default values
      var p = new Array(paramsBare);
      if (paramsNamed) {
        p = p.concat(this.$optional.slice(paramsNamed));
      }
      // Fill in positional args
      var a = new Array(argsLength);
      for (var i = 0; i < argsBare; i++) {
        p[i] = a[i] = '$' + i;
      }
      // Then overwrite with supplied values for optional args
      var lastParameterIndex;
      var namesInOrder = true;
      for (var i = 0; i < argsNamed; i++) {
        var name = names[i];
        a[i + argsBare] = name;
        var j = this.$optional.indexOf(name);
        if (j < 0 || j >= paramsNamed) {
          return function() {
            $throw(new _ArgumentMismatchException(
              'Named argument "' + name + '" was not expected by function.' +
              ' Did you forget to mark the function parameter [optional]?'));
          };
        } else if (lastParameterIndex && lastParameterIndex > j) {
          namesInOrder = false;
        }
        p[j + paramsBare] = name;
        lastParameterIndex = j;
      }

      if (thisLength == argsLength && namesInOrder) {
        // Fast path #2: named arguments, but they're in order and all supplied.
        return this;
      }

      // Note: using Function instead of 'eval' to get a clean scope.
      // TODO(jmesserly): evaluate the performance of these stubs.
      var f = 'function(' + a.join(',') + '){return $f(' + p.join(',') + ');}';
      return new Function('$f', 'return ' + f + '').call(null, this);
    
}
// ********** Code for top level **************
function _constList(other) {
    other.__proto__ = ImmutableList.prototype;
    return other;
}
function _map(itemsAndKeys) {
  var ret = new LinkedHashMapImplementation();
  for (var i = (0);
   i < itemsAndKeys.get$length(); ) {
    ret.$setindex(itemsAndKeys.$index(i++), itemsAndKeys.$index(i++));
  }
  return ret;
}
//  ********** Library node **************
// ********** Code for Process **************
function Process(_process) {
  this.SIGSYS = "SIGSYS";
  this.SIGALRM = "SIGALRM";
  this.SIGXCPU = "SIGXCPU";
  this.SIGTSTP = "SIGTSTP";
  this.SIGSEGV = "SIGSEGV";
  this.SIGQUIT = "SIGQUIT";
  this.SIGABRT = "SIGABRT";
  this.SIGKILL = "SIGKILL";
  this.SIGHUP = "SIGHUP";
  this.SIGUSR2 = "SIGUSR2";
  this.SIGXFSZ = "SIGXFSZ";
  this.SIGCONT = "SIGCONT";
  this.SIGTTOU = "SIGTTOU";
  this.SIGINT = "SIGINT";
  this.SIGURG = "SIGURG";
  this.SIGFPE = "SIGFPE";
  this.SIGUSR1 = "SIGUSR1";
  this.SIGEMT = "SIGEMT";
  this.SIGPIPE = "SIGPIPE";
  this.SIGTTIN = "SIGTTIN";
  this.SIGTERM = "SIGTERM";
  this._process = _process;
  this.SIGBUS = "SIGBUS";
  this.SIGPROF = "SIGPROF";
  this.SIGSTOP = "SIGSTOP";
  this.SIGCHLD = "SIGCHLD";
  this.SIGILL = "SIGILL";
  this.SIGTRAP = "SIGTRAP";
  this.SIGINFO = "SIGINFO";
  this.SIGIO = "SIGIO";
  this.SIGVTALRM = "SIGVTALRM";
  this.SIGWINCH = "SIGWINCH";
}
Process.prototype.get$argv = function() {
  return this._process.argv;
}
Process.prototype.set$argv = function(value) {
  this._process.argv = value;
}
Process.prototype.get$env = function() {
  return new EnvMap(this._process);
}
Process.prototype.exit = function(code) {
  this._process.exit(code);
}
// ********** Code for EnvMap **************
function EnvMap(_process) {
  this._process = _process;
}
EnvMap.prototype.$index = function(key) {
  return this._process.env[key];
}
// ********** Code for ReadableStream **************
// ********** Code for WritableStream **************
$defProp(Object.prototype, '$typeNameOf', (function() {
  function constructorNameWithFallback(obj) {
    var constructor = obj.constructor;
    if (typeof(constructor) == 'function') {
      // The constructor isn't null or undefined at this point. Try
      // to grab hold of its name.
      var name = constructor.name;
      // If the name is a non-empty string, we use that as the type
      // name of this object. On Firefox, we often get 'Object' as
      // the constructor name even for more specialized objects so
      // we have to fall through to the toString() based implementation
      // below in that case.
      if (typeof(name) == 'string' && name && name != 'Object') return name;
    }
    var string = Object.prototype.toString.call(obj);
    return string.substring(8, string.length - 1);
  }

  function chrome$typeNameOf() {
    return this.constructor.name;
  }

  function firefox$typeNameOf() {
    var name = constructorNameWithFallback(this);
    if (name == 'Window') return 'DOMWindow';
    if (name == 'Document') return 'HTMLDocument';
    if (name == 'XMLDocument') return 'Document';
    return name;
  }

  function ie$typeNameOf() {
    var name = constructorNameWithFallback(this);
    if (name == 'Window') return 'DOMWindow';
    // IE calls both HTML and XML documents 'Document', so we check for the
    // xmlVersion property, which is the empty string on HTML documents.
    if (name == 'Document' && this.xmlVersion) return 'Document';
    if (name == 'Document') return 'HTMLDocument';
    return name;
  }

  // If we're not in the browser, we're almost certainly running on v8.
  if (typeof(navigator) != 'object') return chrome$typeNameOf;

  var userAgent = navigator.userAgent;
  if (/Chrome/.test(userAgent)) return chrome$typeNameOf;
  if (/Firefox/.test(userAgent)) return firefox$typeNameOf;
  if (/MSIE/.test(userAgent)) return ie$typeNameOf;
  return function() { return constructorNameWithFallback(this); };
})());
function $dynamic(name) {
  var f = Object.prototype[name];
  if (f && f.methods) return f.methods;

  var methods = {};
  if (f) methods.Object = f;
  function $dynamicBind() {
    // Find the target method
    var obj = this;
    var tag = obj.$typeNameOf();
    var method = methods[tag];
    if (!method) {
      var table = $dynamicMetadata;
      for (var i = 0; i < table.length; i++) {
        var entry = table[i];
        if (entry.map.hasOwnProperty(tag)) {
          method = methods[entry.tag];
          if (method) break;
        }
      }
    }
    method = method || methods.Object;
    var proto = Object.getPrototypeOf(obj);
    if (!proto.hasOwnProperty(name)) {
      $defProp(proto, name, method);
    }

    return method.apply(this, Array.prototype.slice.call(arguments));
  };
  $dynamicBind.methods = methods;
  $defProp(Object.prototype, name, $dynamicBind);
  return methods;
}
if (typeof $dynamicMetadata == 'undefined') $dynamicMetadata = [];
$dynamic("end$0").WriteStream = function() {
  return this.end(null, "utf8");
};
$dynamic("write$1").WriteStream = function($0) {
  return this.write($0, "utf8");
};
// ********** Code for vm **************
vm = require('vm');
// ********** Code for fs **************
fs = require('fs');
// ********** Code for path **************
path = require('path');
// ********** Code for top level **************
function createSandbox() {
  return {'require': require, 'process': process, 'console': console,
        'Buffer' : Buffer,
        'setTimeout$': this.setTimeout, 'clearTimeout': clearTimeout};
}
function get$$_process() {
  return process;
}
function get$$process() {
  return new Process(get$$_process());
}
//  ********** Library file_system **************
// ********** Code for top level **************
function canonicalizePath(path) {
  return path.replaceAll("\\", "/");
}
function joinPaths(path1, path2) {
  path1 = canonicalizePath(path1);
  path2 = canonicalizePath(path2);
  var pieces = path1.split_("/");
  var $$list = path2.split_("/");
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var piece = $$i.next();
    if ($eq$(piece, "..") && pieces.get$length() > (0) && $ne$(pieces.last(), ".") && $ne$(pieces.last(), "..")) {
      pieces.removeLast();
    }
    else if ($ne$(piece, "")) {
      if (pieces.get$length() > (0) && $eq$(pieces.last(), ".")) {
        pieces.removeLast();
      }
      pieces.add(piece);
    }
  }
  return Strings.join(pieces, "/");
}
function dirname(path) {
  path = canonicalizePath(path);
  var lastSlash = path.lastIndexOf("/", path.length);
  if (lastSlash == (-1)) {
    return ".";
  }
  else {
    return path.substring((0), lastSlash);
  }
}
function basename(path) {
  path = canonicalizePath(path);
  var lastSlash = path.lastIndexOf("/", path.length);
  if (lastSlash == (-1)) {
    return path;
  }
  else {
    return path.substring(lastSlash + (1));
  }
}
//  ********** Library file_system_node **************
// ********** Code for NodeFileSystem **************
function NodeFileSystem() {

}
NodeFileSystem.prototype.writeString = function(outfile, text) {
  fs.writeFileSync(outfile, text);
}
NodeFileSystem.prototype.readAll = function(filename) {
  return fs.readFileSync(filename, "utf8");
}
NodeFileSystem.prototype.fileExists = function(filename) {
  return path.existsSync(filename);
}
// ********** Code for top level **************
//  ********** Library lang **************
// ********** Code for MethodAnalyzer **************
function MethodAnalyzer(method, body) {
  this.method = method;
  this.body = body;
  this.hasTypeParams = false;
}
MethodAnalyzer.prototype.get$method = function() { return this.method; };
MethodAnalyzer.prototype.get$body = function() { return this.body; };
MethodAnalyzer.prototype.get$hasTypeParams = function() { return this.hasTypeParams; };
MethodAnalyzer.prototype.analyze = function(context) {
  var thisValue;
  if (context != null) {
    thisValue = context.thisValue;
  }
  else {
    thisValue = new PureStaticValue(this.method.declaringType, null, false, false);
  }
  var values = [];
  var $$list = this.method.parameters;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var p = $$i.next();
    values.add(new PureStaticValue(p.get$type(), null, false, false));
  }
  var args = new Arguments(null, values);
  this._frame = new CallFrame(this, this.method, thisValue, args, context);
  this._bindArguments(this._frame.args);
  var declaredInitializers = this.method.definition.get$dynamic().get$initializers();
  if ($ne$(declaredInitializers)) {
    for (var $$i = declaredInitializers.iterator(); $$i.hasNext(); ) {
      var init = $$i.next();
      if ((init instanceof CallExpression)) {
        this.visitCallExpression(init, true);
      }
    }
  }
  if (this.body != null) this.body.visit(this);
}
MethodAnalyzer.prototype._hasTypeParams = function(node) {
  if ((node instanceof NameTypeReference)) {
    var name = node.get$name().get$name();
    return (this.method.declaringType.lookupTypeParam(name) != null);
  }
  else if ((node instanceof GenericTypeReference)) {
    var $$list = node.get$typeArguments();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var typeArg = $$i.next();
      if (this._hasTypeParams(typeArg)) return true;
    }
    return false;
  }
  else {
    return false;
  }
}
MethodAnalyzer.prototype.resolveType = function(node, typeErrors, allowTypeParams) {
  if (!this.hasTypeParams && this._hasTypeParams(node)) {
    this.hasTypeParams = true;
  }
  return this.method.resolveType(node, typeErrors, allowTypeParams);
}
MethodAnalyzer.prototype.makeNeutral = function(inValue, span) {
  return new PureStaticValue(inValue.get$type(), span, false, false);
}
MethodAnalyzer.prototype._bindArguments = function(args) {
  for (var i = (0);
   i < this.method.parameters.get$length(); i++) {
    var p = this.method.parameters.$index(i);
    var currentArg = null;
    if (i < args.get$bareCount()) {
      currentArg = args.values.$index(i);
    }
    else {
      currentArg = args.getValue(p.get$name());
      if (null == currentArg) {
        p.genValue(this.method, this._frame);
        if (null == p.get$value()) {
          $globals.world.warning("missing argument at call - does not match");
        }
        currentArg = p.get$value();
      }
    }
    currentArg = this.makeNeutral(currentArg, p.get$definition().get$span());
    this._frame.declareParameter(p, currentArg);
  }
}
MethodAnalyzer.prototype.visitBool = function(node) {
  return this.visitTypedValue(node, $globals.world.boolType);
}
MethodAnalyzer.prototype.visitValue = function(node) {
  if (node == null) return null;
  var value = node.visit(this);
  value.checkFirstClass(node.span);
  return value;
}
MethodAnalyzer.prototype.get$visitValue = function() {
  return this.visitValue.bind(this);
}
MethodAnalyzer.prototype.visitTypedValue = function(node, expectedType) {
  var val = this.visitValue(node);
  return null == val ? null : val.convertTo(this._frame, expectedType);
}
MethodAnalyzer.prototype.visitVoid = function(node) {
  return this.visitValue(node);
}
MethodAnalyzer.prototype._visitArgs = function(arguments) {
  var args = [];
  var seenLabel = false;
  for (var $$i = arguments.iterator(); $$i.hasNext(); ) {
    var arg = $$i.next();
    if (arg.get$label() != null) {
      seenLabel = true;
    }
    else if (seenLabel) {
      $globals.world.error("bare argument cannot follow named arguments", arg.get$span());
    }
    args.add(this.visitValue(arg.get$value()));
  }
  return new Arguments(arguments, args);
}
MethodAnalyzer.prototype._makeLambdaMethod = function(name, func) {
  var meth = new MethodMember.lambda$ctor(name, this.method.declaringType, func);
  meth.set$enclosingElement(this.method);
  meth.set$_methodData(new MethodData(meth, this._frame));
  meth.resolve();
  return meth;
}
MethodAnalyzer.prototype._pushBlock = function(node) {
  this._frame.pushBlock(node);
}
MethodAnalyzer.prototype._popBlock = function(node) {
  this._frame.popBlock(node);
}
MethodAnalyzer.prototype._resolveBare = function(name, node) {
  var type = this._frame.method.declaringType;
  var member = type.getMember(name);
  if ($eq$(member) || $ne$(member.get$declaringType(), type)) {
    var libMember = this._frame.get$library().lookup(name, node.span);
    if (null != libMember) return libMember;
  }
  if (null != member && !member.get$isStatic() && this._frame.get$isStatic()) {
    $globals.world.error("cannot refer to instance member from static method", node.span);
  }
  return member;
}
MethodAnalyzer.prototype.visitDietStatement = function(node) {
  var parser = new Parser(node.span.file, false, false, false, node.span.start);
  parser.block().visit(this);
}
MethodAnalyzer.prototype.visitVariableDefinition = function(node) {
  var isFinal = false;
  if (node.modifiers != null && node.modifiers.$index((0)).kind == (99)) {
    isFinal = true;
  }
  var type = this.resolveType(node.type, false, true);
  for (var i = (0);
   i < node.names.get$length(); i++) {
    var name = node.names.$index(i).name;
    var value = this.visitValue(node.values.$index(i));
    this._frame.create(name, type, node.names.$index(i), isFinal, value);
  }
}
MethodAnalyzer.prototype.visitFunctionDefinition = function(node) {
  var meth = this._makeLambdaMethod(node.name.name, node);
  var funcValue = this._frame.create(meth.get$name(), meth.get$functionType(), this.method.definition, true, null);
  meth.get$methodData().analyze();
}
MethodAnalyzer.prototype.visitReturnStatement = function(node) {
  if (node.value == null) {
    this._frame.returns(Value.fromNull(node.span));
  }
  else {
    this._frame.returns(this.visitValue(node.value));
  }
}
MethodAnalyzer.prototype.visitThrowStatement = function(node) {
  if (node.value != null) {
    var value = this.visitValue(node.value);
  }
  else {
  }
}
MethodAnalyzer.prototype.visitAssertStatement = function(node) {
  var test = this.visitValue(node.test);
}
MethodAnalyzer.prototype.visitBreakStatement = function(node) {

}
MethodAnalyzer.prototype.visitContinueStatement = function(node) {

}
MethodAnalyzer.prototype.visitIfStatement = function(node) {
  var test = this.visitBool(node.test);
  node.trueBranch.visit(this);
  if (node.falseBranch != null) {
    node.falseBranch.visit(this);
  }
}
MethodAnalyzer.prototype.visitWhileStatement = function(node) {
  var test = this.visitBool(node.test);
  node.body.visit(this);
}
MethodAnalyzer.prototype.visitDoStatement = function(node) {
  node.body.visit(this);
  var test = this.visitBool(node.test);
}
MethodAnalyzer.prototype.visitForStatement = function(node) {
  this._pushBlock(node);
  if (node.init != null) node.init.visit(this);
  if (node.test != null) {
    var test = this.visitBool(node.test);
  }
  var $$list = node.step;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var s = $$i.next();
    var sv = this.visitVoid(s);
  }
  this._pushBlock(node.body);
  node.body.visit(this);
  this._popBlock(node.body);
  this._popBlock(node);
}
MethodAnalyzer.prototype.visitForInStatement = function(node) {
  var itemType = this.resolveType(node.item.type, false, true);
  var list = node.list.visit(this);
  this._visitForInBody(node, itemType, list);
}
MethodAnalyzer.prototype._isFinal = function(typeRef) {
  if ((typeRef instanceof GenericTypeReference)) {
    typeRef = typeRef.get$baseType();
  }
  else if ((typeRef instanceof SimpleTypeReference)) {
    return false;
  }
  return $ne$(typeRef) && typeRef.get$isFinal();
}
MethodAnalyzer.prototype._visitForInBody = function(node, itemType, list) {
  this._pushBlock(node);
  var isFinal = this._isFinal(node.item.type);
  var itemName = node.item.name.name;
  var item = this._frame.create(itemName, itemType, node.item.name, isFinal, null);
  var iterator = list.invoke(this._frame, "iterator", node.list, Arguments.get$EMPTY());
  node.body.visit(this);
  this._popBlock(node);
}
MethodAnalyzer.prototype._createDI = function(di) {
  this._frame.create(di.name.name, this.resolveType(di.type, false, true), di.name, true, null);
}
MethodAnalyzer.prototype.visitTryStatement = function(node) {
  this._pushBlock(node.body);
  node.body.visit(this);
  this._popBlock(node.body);
  if (node.catches.get$length() > (0)) {
    for (var i = (0);
     i < node.catches.get$length(); i++) {
      var catch_ = node.catches.$index(i);
      this._pushBlock(catch_);
      this._createDI(catch_.get$exception());
      if (null != catch_.get$trace()) {
        this._createDI(catch_.get$trace());
      }
      catch_.get$body().visit(this);
      this._popBlock(catch_);
    }
  }
  if (node.finallyBlock != null) {
    node.finallyBlock.visit(this);
  }
}
MethodAnalyzer.prototype.visitSwitchStatement = function(node) {
  var test = this.visitValue(node.test);
  var $$list = node.cases;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var case_ = $$i.next();
    this._pushBlock(case_);
    for (var i = (0);
     i < case_.get$cases().get$length(); i++) {
      var expr = case_.get$cases().$index(i);
      if ($eq$(expr)) {
      }
      else {
        var value = this.visitValue(expr);
      }
    }
    this._visitAllStatements(case_.get$statements());
    this._popBlock(case_);
  }
}
MethodAnalyzer.prototype._visitAllStatements = function(statementList) {
  for (var i = (0);
   i < statementList.get$length(); i++) {
    var stmt = statementList.$index(i);
    stmt.visit(this);
  }
}
MethodAnalyzer.prototype.visitBlockStatement = function(node) {
  this._pushBlock(node);
  this._visitAllStatements(node.body);
  this._popBlock(node);
}
MethodAnalyzer.prototype.visitLabeledStatement = function(node) {
  node.body.visit(this);
}
MethodAnalyzer.prototype.visitExpressionStatement = function(node) {
  var value = this.visitVoid(node.body);
}
MethodAnalyzer.prototype.visitEmptyStatement = function(node) {

}
MethodAnalyzer.prototype.visitLambdaExpression = function(node) {
  var name = (node.func.name != null) ? node.func.name.name : "";
  var meth = this._makeLambdaMethod(name, node.func);
  meth.get$methodData().analyze();
  return this._frame._makeValue($globals.world.functionType, node);
}
MethodAnalyzer.prototype.analyzeInitializerConstructorCall = function(node, receiver, name) {
  var type = this._frame.method.declaringType;
  if ((receiver instanceof SuperExpression)) {
    type = type.get$parent();
  }
  var member = type.getConstructor(name == null ? "" : name);
  if (null != member) {
    return member.invoke(this._frame, node, this._frame.makeThisValue(node), this._visitArgs(node.arguments));
  }
  else {
    var constructorName = name == null ? "" : ("." + name);
    $globals.world.warning(("cannot find constructor \"" + type.get$name() + constructorName + "\""), node.span);
    return this._frame._makeValue($globals.world.varType, node);
  }
}
MethodAnalyzer.prototype.isThisOrSuper = function(node) {
  return (node instanceof ThisExpression) || (node instanceof SuperExpression);
}
MethodAnalyzer.prototype.visitCallExpression = function(node, visitingInitializers) {
  var target;
  var position = node.target;
  var name = ":call";
  if ((node.target instanceof DotExpression)) {
    var dot = node.target;
    target = dot.self.visit(this);
    name = dot.name.name;
    if (this.isThisOrSuper(dot.self) && visitingInitializers) {
      return this.analyzeInitializerConstructorCall(node, dot.self, name);
    }
    else {
      position = dot.name;
    }
  }
  else if (this.isThisOrSuper(node.target) && visitingInitializers) {
    return this.analyzeInitializerConstructorCall(node, node.target, null);
  }
  else if ((node.target instanceof VarExpression)) {
    var varExpr = node.target;
    name = varExpr.name.name;
    target = this._frame.lookup(name);
    if ($ne$(target)) {
      return target.get(position).invoke(this._frame, ":call", node, this._visitArgs(node.arguments));
    }
    var member = this._resolveBare(name, varExpr.name);
    if (null != member) {
      return member.invoke(this._frame, node, this._frame.makeThisValue(node), this._visitArgs(node.arguments));
    }
    else {
      $globals.world.warning(("cannot find \"" + name + "\""), node.span);
      return this._frame._makeValue($globals.world.varType, node);
    }
  }
  else {
    target = node.target.visit(this);
  }
  return target.invoke(this._frame, name, position, this._visitArgs(node.arguments));
}
MethodAnalyzer.prototype.visitIndexExpression = function(node) {
  var target = this.visitValue(node.target);
  var index = this.visitValue(node.index);
  return target.invoke(this._frame, ":index", node, new Arguments(null, [index]));
}
MethodAnalyzer.prototype.visitBinaryExpression = function(node, isVoid) {
  var kind = node.op.kind;
  if ($eq$(kind, (35)) || $eq$(kind, (34))) {
    var xb = this.visitBool(node.x);
    var yb = this.visitBool(node.y);
    return xb.binop(kind, yb, this._frame, node);
  }
  var assignKind = TokenKind.kindFromAssign(node.op.kind);
  if ($eq$(assignKind, (-1))) {
    var x = this.visitValue(node.x);
    var y = this.visitValue(node.y);
    return x.binop(kind, y, this._frame, node);
  }
  else {
    return this._visitAssign(assignKind, node.x, node.y, node);
  }
}
MethodAnalyzer.prototype._visitAssign = function(kind, xn, yn, position) {
  if ((xn instanceof VarExpression)) {
    return this._visitVarAssign(kind, xn, yn, position);
  }
  else if ((xn instanceof IndexExpression)) {
    return this._visitIndexAssign(kind, xn, yn, position);
  }
  else if ((xn instanceof DotExpression)) {
    return this._visitDotAssign(kind, xn, yn, position);
  }
  else {
    $globals.world.error("illegal lhs", xn.span);
  }
}
MethodAnalyzer.prototype._visitVarAssign = function(kind, xn, yn, node) {
  var value = this.visitValue(yn);
  var name = xn.name.name;
  var slot = this._frame.lookup(name);
  if ($ne$(slot)) {
    slot.set(value);
  }
  else {
    var member = this._resolveBare(name, xn.name);
    if (null != member) {
      member._set(this._frame, node, this._frame.makeThisValue(node), value);
    }
    else {
      $globals.world.warning(("cannot find \"" + name + "\""), node.span);
    }
  }
  return this._frame._makeValue(value.get$type(), node);
}
MethodAnalyzer.prototype._visitIndexAssign = function(kind, xn, yn, position) {
  var target = this.visitValue(xn.target);
  var index = this.visitValue(xn.index);
  var y = this.visitValue(yn);
  return target.setIndex$4$kind(this._frame, index, position, y, kind);
}
MethodAnalyzer.prototype._visitDotAssign = function(kind, xn, yn, position) {
  var target = xn.self.visit(this);
  var y = this.visitValue(yn);
  return target.set_$4$kind(this._frame, xn.name.name, xn.name, y, kind);
}
MethodAnalyzer.prototype.visitUnaryExpression = function(node) {
  var value = this.visitValue(node.self);
  switch (node.op.kind) {
    case (16):
    case (17):

      return value.binop((42), this._frame._makeValue($globals.world.intType, node), this._frame, node);

  }
  return value.unop(node.op.kind, this._frame, node);
}
MethodAnalyzer.prototype.visitDeclaredIdentifier = function(node) {
  $globals.world.error("Expected expression", node.span);
}
MethodAnalyzer.prototype.visitAwaitExpression = function(node) {
  $globals.world.internalError("Await expressions should have been eliminated before code generation", node.span);
}
MethodAnalyzer.prototype.visitPostfixExpression = function(node, isVoid) {
  var value = this.visitValue(node.body);
  return this._frame._makeValue(value.get$type(), node);
}
MethodAnalyzer.prototype.visitNewExpression = function(node) {
  var typeRef = node.type;
  var constructorName = "";
  if (node.name != null) {
    constructorName = node.name.name;
  }
  if ($eq$(constructorName, "") && (typeRef instanceof NameTypeReference) && typeRef.get$names() != null) {
    var names = ListFactory.ListFactory$from$factory(typeRef.get$names());
    constructorName = names.removeLast().get$name();
    if (names.get$length() == (0)) names = null;
    typeRef = new NameTypeReference(typeRef.get$isFinal(), typeRef.get$name(), names, typeRef.get$span());
  }
  var type = this.resolveType(typeRef, true, true);
  if (type.get$isTop()) {
    type = type.get$library().findTypeByName(constructorName);
    if ($eq$(type)) {
      $globals.world.error(("cannot resolve type " + constructorName), node.span);
    }
    constructorName = "";
  }
  if ((type instanceof ParameterType)) {
    $globals.world.error("cannot instantiate a type parameter", node.span);
    return this._frame._makeValue($globals.world.varType, node);
  }
  var m = type.getConstructor(constructorName);
  if ($eq$(m)) {
    var name = type.get$jsname();
    if (type.get$isVar()) {
      name = typeRef.get$name().get$name();
    }
    $globals.world.warning(("no matching constructor for " + name), node.span);
    return this._frame._makeValue(type, node);
  }
  if (node.isConst) {
    if (!m.get$isConst()) {
      $globals.world.error("can't use const on a non-const constructor", node.span);
    }
    var $$list = node.arguments;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var arg = $$i.next();
      if (!this.visitValue(arg.get$value()).get$isConst()) {
        $globals.world.error("const constructor expects const arguments", arg.get$span());
      }
    }
  }
  var args = this._visitArgs(node.arguments);
  var target = new TypeValue(type, typeRef.get$span());
  return new PureStaticValue(type, node.span, node.isConst, false);
}
MethodAnalyzer.prototype.visitListExpression = function(node) {
  var argValues = [];
  var listType = $globals.world.listType;
  var type = $globals.world.varType;
  if (node.itemType != null) {
    type = this.resolveType(node.itemType, true, !node.isConst);
    if (node.isConst && ((type instanceof ParameterType) || type.get$hasTypeParams())) {
      $globals.world.error("type parameter cannot be used in const list literals");
    }
    listType = listType.getOrMakeConcreteType([type]);
  }
  var $$list = node.values;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var item = $$i.next();
    var arg = this.visitTypedValue(item, type);
    argValues.add(arg);
  }
  $globals.world.listFactoryType.markUsed();
  return new PureStaticValue(listType, node.span, node.isConst, false);
}
MethodAnalyzer.prototype.visitMapExpression = function(node) {
  var values = [];
  var valueType = $globals.world.varType, keyType = $globals.world.stringType;
  var mapType = $globals.world.mapType;
  if (null != node.valueType) {
    if (null != node.keyType) {
      keyType = this.method.resolveType(node.keyType, true, !node.isConst);
      if (!keyType.get$isString()) {
        $globals.world.error("the key type of a map literal must be \"String\"", keyType.get$span());
      }
      if (node.isConst && ((keyType instanceof ParameterType) || keyType.get$hasTypeParams())) {
        $globals.world.error("type parameter cannot be used in const map literals");
      }
    }
    valueType = this.resolveType(node.valueType, true, !node.isConst);
    if (node.isConst && ((valueType instanceof ParameterType) || valueType.get$hasTypeParams())) {
      $globals.world.error("type parameter cannot be used in const map literals");
    }
    mapType = mapType.getOrMakeConcreteType([keyType, valueType]);
  }
  for (var i = (0);
   i < node.items.get$length(); i += (2)) {
    var key = this.visitTypedValue(node.items.$index(i), keyType);
    values.add(key);
    var value = this.visitTypedValue(node.items.$index(i + (1)), valueType);
    if (node.isConst && !value.get$isConst()) {
      $globals.world.error("const map can only contain const values", value.get$span());
    }
    values.add(value);
  }
  return new PureStaticValue(mapType, node.span, node.isConst, false);
}
MethodAnalyzer.prototype.visitConditionalExpression = function(node) {
  var test = this.visitBool(node.test);
  var trueBranch = this.visitValue(node.trueBranch);
  var falseBranch = this.visitValue(node.falseBranch);
  return this._frame._makeValue(Type.union(trueBranch.get$type(), falseBranch.get$type()), node);
}
MethodAnalyzer.prototype.visitIsExpression = function(node) {
  var value = this.visitValue(node.x);
  var type = this.resolveType(node.type, false, true);
  return this._frame._makeValue($globals.world.boolType, node);
}
MethodAnalyzer.prototype.visitParenExpression = function(node) {
  return this.visitValue(node.body);
}
MethodAnalyzer.prototype.visitDotExpression = function(node) {
  var target = node.self.visit(this);
  return target.get_(this._frame, node.name.name, node);
}
MethodAnalyzer.prototype.visitVarExpression = function(node) {
  var name = node.name.name;
  var slot = this._frame.lookup(name);
  if ($ne$(slot)) {
    return slot.get(node);
  }
  var member = this._resolveBare(name, node.name);
  if (null != member) {
    if ((member instanceof TypeMember)) {
      return new PureStaticValue(member.get$dynamic().get$type(), node.span, true, true);
    }
    else {
      return member._get(this._frame, node, this._frame.makeThisValue(node));
    }
  }
  else {
    $globals.world.warning(("cannot find \"" + name + "\""), node.span);
    return this._frame._makeValue($globals.world.varType, node);
  }
}
MethodAnalyzer.prototype.visitThisExpression = function(node) {
  return this._frame.makeThisValue(node);
}
MethodAnalyzer.prototype.visitSuperExpression = function(node) {
  return this._frame.makeSuperValue(node);
}
MethodAnalyzer.prototype.visitLiteralExpression = function(node) {
  return new PureStaticValue(node.value.get$type(), node.span, true, false);
}
MethodAnalyzer.prototype.visitStringInterpExpression = function(node) {
  node.pieces.forEach(this.get$visitValue());
  return this._frame._makeValue($globals.world.stringType, node);
}
MethodAnalyzer.prototype._pushBlock$1 = MethodAnalyzer.prototype._pushBlock;
MethodAnalyzer.prototype.analyze$1 = MethodAnalyzer.prototype.analyze;
MethodAnalyzer.prototype.visitBinaryExpression$1 = function($0) {
  return this.visitBinaryExpression($0, false);
};
MethodAnalyzer.prototype.visitCallExpression$1 = function($0) {
  return this.visitCallExpression($0, false);
};
MethodAnalyzer.prototype.visitPostfixExpression$1 = function($0) {
  return this.visitPostfixExpression($0, false);
};
// ********** Code for CallFrame **************
function CallFrame(analyzer, method, thisValue, args, enclosingFrame) {
  this.args = args;
  this.analyzer = analyzer;
  this.enclosingFrame = enclosingFrame;
  this.method = method;
  this.thisValue = thisValue;
  this._slots = [];
  this._scope = new AnalyzeScope(null, this, this.analyzer.body);
  this._returnSlot = new VariableSlot(this._scope, "return", this.method.returnType, this.analyzer.body, false);
}
CallFrame.prototype.findMembers = function(name) {
  return this.get$library()._findMembers(name);
}
CallFrame.prototype.get$counters = function() {
  return $globals.world.counters;
}
CallFrame.prototype.get$library = function() {
  return this.method.get$library();
}
CallFrame.prototype.get$method = function() { return this.method; };
CallFrame.prototype.get$needsCode = function() {
  return false;
}
CallFrame.prototype.get$showWarnings = function() {
  return true;
}
CallFrame.prototype._makeThisCode = function() {
  return null;
}
CallFrame.prototype.getTemp = function(value) {
  return null;
}
CallFrame.prototype.forceTemp = function(value) {
  return null;
}
CallFrame.prototype.assignTemp = function(tmp, v) {
  return null;
}
CallFrame.prototype.freeTemp = function(value) {
  return null;
}
CallFrame.prototype.get$isStatic = function() {
  return this.enclosingFrame != null ? this.enclosingFrame.get$isStatic() : this.method.isStatic;
}
CallFrame.prototype.get$_slots = function() { return this._slots; };
CallFrame.prototype.get$_scope = function() { return this._scope; };
CallFrame.prototype.pushBlock = function(node) {
  this._scope = new AnalyzeScope(this._scope, this, node);
}
CallFrame.prototype.popBlock = function(node) {
  if ($ne$(this._scope.node, node)) {
    $globals.world.internalError("incorrect pop", node.span, this._scope.node.span);
  }
  this._scope = this._scope.parent;
}
CallFrame.prototype.returns = function(value) {
  this._returnSlot.set(value);
}
CallFrame.prototype.lookup = function(name) {
  var slot = this._scope._lookup(name);
  if ($eq$(slot) && this.enclosingFrame != null) {
    return this.enclosingFrame.lookup(name);
  }
  return slot;
}
CallFrame.prototype.create = function(name, staticType, node, isFinal, value) {
  var slot = new VariableSlot(this._scope, name, staticType, node, isFinal, value);
  var existingSlot = this._scope._lookup(name);
  if (null != existingSlot) {
    if ($eq$(existingSlot.get$scope(), this)) {
      $globals.world.error(("duplicate name \"" + name + "\""), node.span);
    }
    else {
    }
  }
  this._slots.add(slot);
  this._scope._slots.add(slot);
}
CallFrame.prototype.declareParameter = function(p, value) {
  return this.create(p.name, p.type, p.definition, false, value);
}
CallFrame.prototype._makeValue = function(type, node) {
  return new PureStaticValue(type, node == null ? null : node.span, false, false);
}
CallFrame.prototype.makeSuperValue = function(node) {
  return this._makeValue(this.thisValue.get$type().get$parent(), node);
}
CallFrame.prototype.makeThisValue = function(node) {
  return this._makeValue(this.thisValue.get$type(), node);
}
// ********** Code for VariableSlot **************
function VariableSlot(scope, name, staticType, node, isFinal, value) {
  this.value = value;
  this.name = name;
  this.scope = scope;
  this.node = node;
  this.staticType = staticType;
  this.isFinal = isFinal;
  if (null != this.value) {
    this.value = this.value.convertTo(this.scope.frame, this.staticType);
  }
}
VariableSlot.prototype.get$scope = function() { return this.scope; };
VariableSlot.prototype.get$name = function() { return this.name; };
VariableSlot.prototype.get$staticType = function() { return this.staticType; };
VariableSlot.prototype.get$isFinal = function() { return this.isFinal; };
VariableSlot.prototype.get$value = function() { return this.value; };
VariableSlot.prototype.set$value = function(value) { return this.value = value; };
VariableSlot.prototype.get = function(position) {
  return this.scope.frame._makeValue(this.staticType, position);
}
VariableSlot.prototype.set = function(newValue) {
  if (null != newValue) {
    newValue = newValue.convertTo(this.scope.frame, this.staticType);
  }
  this.value = Value.union(this.value, newValue);
}
VariableSlot.prototype.toString = function() {
  var valueString = null != this.value ? (" = " + this.value.get$type().name) : "";
  return ("" + this.staticType.name + " " + this.name + valueString);
}
VariableSlot.prototype.toString$0 = VariableSlot.prototype.toString;
// ********** Code for AnalyzeScope **************
function AnalyzeScope(parent, frame, node) {
  this.frame = frame;
  this.parent = parent;
  this.node = node;
  this._slots = [];
}
AnalyzeScope.prototype.get$parent = function() { return this.parent; };
AnalyzeScope.prototype.get$_slots = function() { return this._slots; };
AnalyzeScope.prototype._lookup = function(name) {
  for (var s = this;
   $ne$(s); s = s.get$parent()) {
    for (var i = (0);
     i < s.get$_slots().get$length(); i++) {
      var ret = s.get$_slots().$index(i);
      if ($eq$(ret.get$name(), name)) return ret;
    }
  }
  return null;
}
// ********** Code for BlockScope **************
function BlockScope(enclosingMethod, parent, node, reentrant) {
  this.enclosingMethod = enclosingMethod;
  this._vars = new CopyOnWriteMap_dart_core_String$VariableValue();
  this.parent = parent;
  this.node = node;
  this.reentrant = reentrant;
  this._jsNames = new HashSetImplementation_dart_core_String();
  if (this.get$isMethodScope()) {
    this._closedOver = new HashSetImplementation_dart_core_String();
  }
  else {
    this.reentrant = reentrant || this.parent.reentrant;
  }
  this.inferTypes = $globals.options.inferTypes && (this.parent == null || this.parent.inferTypes);
}
BlockScope._snapshot$ctor = function(original) {
  this.enclosingMethod = original.enclosingMethod;
  this._vars = original._vars.clone();
  this.parent = original.parent == null ? null : original.parent.snapshot();
  this.node = original.node;
  this.inferTypes = original.inferTypes;
  this._jsNames = original._jsNames;
  this._closedOver = original._closedOver;
  this.rethrow = original.rethrow;
}
BlockScope._snapshot$ctor.prototype = BlockScope.prototype;
BlockScope.prototype.get$enclosingMethod = function() { return this.enclosingMethod; };
BlockScope.prototype.get$parent = function() { return this.parent; };
BlockScope.prototype.get$_vars = function() { return this._vars; };
BlockScope.prototype.get$_jsNames = function() { return this._jsNames; };
BlockScope.prototype.get$_closedOver = function() { return this._closedOver; };
BlockScope.prototype.get$rethrow = function() { return this.rethrow; };
BlockScope.prototype.get$isMethodScope = function() {
  return this.parent == null || $ne$(this.parent.enclosingMethod, this.enclosingMethod);
}
BlockScope.prototype.get$methodScope = function() {
  var s = this;
  while (!s.get$isMethodScope()) s = s.get$parent();
  return s;
}
BlockScope.prototype.lookup = function(name) {
  for (var s = this;
   $ne$(s); s = s.get$parent()) {
    var ret = s.get$_vars().$index(name);
    if (ret != null) return this._capture(s, ret);
  }
  return null;
}
BlockScope.prototype.inferAssign = function(name, value) {
  if (this.inferTypes) this.assign(name, value);
}
BlockScope.prototype.assign = function(name, value) {
  for (var s = this;
   $ne$(s); s = s.get$parent()) {
    var existing = s.get$_vars().$index(name);
    if ($ne$(existing)) {
      s.get$_vars().$setindex(name, existing.replaceValue(value));
      return;
    }
  }
  $globals.world.internalError(("assigning variable '" + name + "' that doesn't exist."));
}
BlockScope.prototype._capture = function(other, value) {
  if ($ne$(other.enclosingMethod, this.enclosingMethod)) {
    other.get$methodScope()._closedOver.add(value.get$code());
    if (this.enclosingMethod.captures != null && other.reentrant) {
      this.enclosingMethod.captures.add(value.get$code());
    }
  }
  return value;
}
BlockScope.prototype._isDefinedInParent = function(name) {
  if (this.get$isMethodScope() && this._closedOver.contains(name)) return true;
  for (var s = this.parent;
   $ne$(s); s = s.get$parent()) {
    if (s.get$_vars().containsKey(name)) return true;
    if (s.get$_jsNames().contains(name)) return true;
    if (s.get$isMethodScope() && s.get$_closedOver().contains(name)) return true;
  }
  var type = this.enclosingMethod.method.declaringType;
  if (type.get$library().lookup(name, null) != null) return true;
  return false;
}
BlockScope.prototype.create = function(name, type, span, isFinal, isParameter) {
  var jsName = $globals.world.toJsIdentifier(name);
  if (this._vars.containsKey(name)) {
    $globals.world.error(("duplicate name \"" + name + "\""), span);
  }
  if (!isParameter) {
    var index = (0);
    while (this._isDefinedInParent(jsName)) {
      jsName = ("" + name + (index++));
    }
  }
  var ret = new VariableValue(type, jsName, span, isFinal);
  this._vars.$setindex(name, ret);
  if (name != jsName) this._jsNames.add(jsName);
  return ret;
}
BlockScope.prototype.declareParameter = function(p) {
  return this.create(p.name, p.type, p.definition.span, false, true);
}
BlockScope.prototype.declare = function(id) {
  var type = this.enclosingMethod.method.resolveType(id.type, false, true);
  return this.create(id.name.name, type, id.span, false, false);
}
BlockScope.prototype.getRethrow = function() {
  var scope = this;
  while (scope.get$rethrow() == null && $ne$(scope.get$parent())) {
    scope = scope.get$parent();
  }
  return scope.get$rethrow();
}
BlockScope.prototype.snapshot = function() {
  return new BlockScope._snapshot$ctor(this);
}
BlockScope.prototype.unionWith = function(other) {
  var $this = this; // closure support
  var $0;
  var changed = false;
  if (this.parent != null) {
    changed = this.parent.unionWith(other.parent);
  }
  if ((($0 = this._vars._lang_map) == null ? null != (other._vars._lang_map) : $0 !== other._vars._lang_map)) {
    other._vars.forEach((function (key, otherVar) {
      var $0;
      var myVar = $this._vars.$index(key);
      var v = Value.union(myVar.value, otherVar.value);
      if ((($0 = myVar.value) == null ? null != (v) : $0 !== v)) {
        $this._vars.$setindex(key, myVar.replaceValue(v));
        changed = true;
      }
    })
    );
  }
  return changed;
}
BlockScope.prototype.create$3$isFinal = function($0, $1, $2, isFinal) {
  return this.create($0, $1, $2, isFinal, false);
};
// ********** Code for CodeWriter **************
function CodeWriter() {
  this._indentation = (0);
  this.writeComments = true;
  this._pendingIndent = false;
  this._buf = new StringBufferImpl("");
}
CodeWriter.prototype.get$text = function() {
  return this._buf.toString();
}
CodeWriter.prototype._indent = function() {
  this._pendingIndent = false;
  for (var i = (0);
   i < this._indentation; i++) {
    this._buf.add("  ");
  }
}
CodeWriter.prototype.comment = function(text) {
  if (this.writeComments) {
    this.writeln(text);
  }
}
CodeWriter.prototype.write = function(text) {
  if (text.length == (0)) return;
  if (this._pendingIndent) this._indent();
  if (text.indexOf("\n") != (-1)) {
    var lines = text.split_("\n");
    for (var i = (0);
     i < lines.get$length() - (1); i++) {
      this.writeln(lines.$index(i));
    }
    this.write(lines.$index(lines.get$length() - (1)));
  }
  else {
    this._buf.add(text);
  }
}
CodeWriter.prototype.writeln = function(text) {
  if (text != null) {
    this.write(text);
  }
  if (!text.endsWith("\n")) this._buf.add("\n");
  this._pendingIndent = true;
}
CodeWriter.prototype.writeln.$optional = ['text', 'null']
CodeWriter.prototype.get$writeln = function() {
  return this.writeln.bind(this);
}
CodeWriter.prototype.enterBlock = function(text) {
  this.writeln(text);
  this._indentation++;
}
CodeWriter.prototype.get$enterBlock = function() {
  return this.enterBlock.bind(this);
}
CodeWriter.prototype.exitBlock = function(text) {
  this._indentation--;
  this.writeln(text);
}
CodeWriter.prototype.nextBlock = function(text) {
  this._indentation--;
  this.writeln(text);
  this._indentation++;
}
CodeWriter.prototype.write$1 = CodeWriter.prototype.write;
// ********** Code for CoreJs **************
function CoreJs() {
  this.useIsolates = false;
  this._generatedTypeNameOf = false;
  this._usedOperators = new HashMapImplementation();
  this._generatedInherits = false;
  this.useNotNullBool = false;
  this._generatedDynamicSetMetadata = false;
  this.writer = new CodeWriter();
  this.useWrap0 = false;
  this.useThrow = false;
  this._generatedDynamicProto = false;
  this._generatedBind = false;
  this.useWrap1 = false;
  this.useSetIndex = false;
  this.useIndex = false;
  this._generatedDefProp = false;
}
CoreJs.prototype.get$writer = function() { return this.writer; };
CoreJs.prototype.set$writer = function(value) { return this.writer = value; };
CoreJs.prototype.markCorelibTypeUsed = function(typeName) {
  $globals.world.gen.markTypeUsed($globals.world.corelib.types.$index(typeName));
}
CoreJs.prototype.useOperator = function(name) {
  if ($ne$(this._usedOperators.$index(name))) return;
  if (name != ":ne" && name != ":eq") {
    this.markCorelibTypeUsed("NoSuchMethodException");
  }
  if (name != ":bit_not" && name != ":negate") {
    this.markCorelibTypeUsed("IllegalArgumentException");
  }
  var code;
  switch (name) {
    case ":ne":

      code = "function $ne$(x, y) {\n  if (x == null) return y != null;\n  return (typeof(x) != 'object') ? x !== y : !x.$eq(y);\n}";
      break;

    case ":eq":

      this.ensureDefProp();
      code = "function $eq$(x, y) {\n  if (x == null) return y == null;\n  return (typeof(x) != 'object') ? x === y : x.$eq(y);\n}\n// TODO(jimhug): Should this or should it not match equals?\n$defProp(Object.prototype, '$eq', function(other) {\n  return this === other;\n});";
      break;

    case ":bit_not":

      code = "function $bit_not$(x) {\n  if (typeof(x) == 'number') return ~x;\n  if (typeof(x) == 'object') return  x.$bit_not();\n  $throw(new NoSuchMethodException(x, \"operator ~\", []));\n}";
      break;

    case ":negate":

      code = "function $negate$(x) {\n  if (typeof(x) == 'number') return -x;\n  if (typeof(x) == 'object') return x.$negate();\n  $throw(new NoSuchMethodException(x, \"operator negate\", []));\n}";
      break;

    case ":add":

      code = "function $add$complex$(x, y) {\n  if (typeof(x) == 'number') {\n    $throw(new IllegalArgumentException(y));\n  } else if (typeof(x) == 'string') {\n    var str = (y == null) ? 'null' : y.toString();\n    if (typeof(str) != 'string') {\n      throw new Error(\"calling toString() on right hand operand of operator \" +\n      \"+ did not return a String\");\n    }\n    return x + str;\n  } else if (typeof(x) == 'object') {\n    return x.$add(y);\n  } else {\n    $throw(new NoSuchMethodException(x, \"operator +\", [y]));\n  }\n}\n\nfunction $add$(x, y) {\n  if (typeof(x) == 'number' && typeof(y) == 'number') return x + y;\n  return $add$complex$(x, y);\n}";
      break;

    case ":truncdiv":

      this.useThrow = true;
      this.markCorelibTypeUsed("IntegerDivisionByZeroException");
      code = "function $truncdiv$(x, y) {\n  if (typeof(x) == 'number') {\n    if (typeof(y) == 'number') {\n      if (y == 0) $throw(new IntegerDivisionByZeroException());\n      var tmp = x / y;\n      return (tmp < 0) ? Math.ceil(tmp) : Math.floor(tmp);\n    } else {\n      $throw(new IllegalArgumentException(y));\n    }\n  } else if (typeof(x) == 'object') {\n    return x.$truncdiv(y);\n  } else {\n    $throw(new NoSuchMethodException(x, \"operator ~/\", [y]));\n  }\n}";
      break;

    case ":mod":

      code = "function $mod$(x, y) {\n  if (typeof(x) == 'number') {\n    if (typeof(y) == 'number') {\n      var result = x % y;\n      if (result == 0) {\n        return 0;  // Make sure we don't return -0.0.\n      } else if (result < 0) {\n        if (y < 0) {\n          return result - y;\n        } else {\n          return result + y;\n        }\n      }\n      return result;\n    } else {\n      $throw(new IllegalArgumentException(y));\n    }\n  } else if (typeof(x) == 'object') {\n    return x.$mod(y);\n  } else {\n    $throw(new NoSuchMethodException(x, \"operator %\", [y]));\n  }\n}";
      break;

    default:

      var op = TokenKind.rawOperatorFromMethod(name);
      var jsname = $globals.world.toJsIdentifier(name);
      code = _otherOperator(jsname, op);
      break;

  }
  this._usedOperators.$setindex(name, code);
}
CoreJs.prototype.ensureDynamicProto = function() {
  if (this._generatedDynamicProto) return;
  this._generatedDynamicProto = true;
  this.ensureTypeNameOf();
  this.ensureDefProp();
  this.writer.writeln("function $dynamic(name) {\n  var f = Object.prototype[name];\n  if (f && f.methods) return f.methods;\n\n  var methods = {};\n  if (f) methods.Object = f;\n  function $dynamicBind() {\n    // Find the target method\n    var obj = this;\n    var tag = obj.$typeNameOf();\n    var method = methods[tag];\n    if (!method) {\n      var table = $dynamicMetadata;\n      for (var i = 0; i < table.length; i++) {\n        var entry = table[i];\n        if (entry.map.hasOwnProperty(tag)) {\n          method = methods[entry.tag];\n          if (method) break;\n        }\n      }\n    }\n    method = method || methods.Object;\n    var proto = Object.getPrototypeOf(obj);\n    if (!proto.hasOwnProperty(name)) {\n      $defProp(proto, name, method);\n    }\n\n    return method.apply(this, Array.prototype.slice.call(arguments));\n  };\n  $dynamicBind.methods = methods;\n  $defProp(Object.prototype, name, $dynamicBind);\n  return methods;\n}\nif (typeof $dynamicMetadata == 'undefined') $dynamicMetadata = [];\n");
}
CoreJs.prototype.ensureDynamicSetMetadata = function() {
  if (this._generatedDynamicSetMetadata) return;
  this._generatedDynamicSetMetadata = true;
  this.writer.writeln("function $dynamicSetMetadata(inputTable) {\n  // TODO: Deal with light isolates.\n  var table = [];\n  for (var i = 0; i < inputTable.length; i++) {\n    var tag = inputTable[i][0];\n    var tags = inputTable[i][1];\n    var map = {};\n    var tagNames = tags.split('|');\n    for (var j = 0; j < tagNames.length; j++) {\n      map[tagNames[j]] = true;\n    }\n    table.push({tag: tag, tags: tags, map: map});\n  }\n  $dynamicMetadata = table;\n}\n");
}
CoreJs.prototype.ensureTypeNameOf = function() {
  if (this._generatedTypeNameOf) return;
  this._generatedTypeNameOf = true;
  this.ensureDefProp();
  this.writer.writeln("$defProp(Object.prototype, '$typeNameOf', (function() {\n  function constructorNameWithFallback(obj) {\n    var constructor = obj.constructor;\n    if (typeof(constructor) == 'function') {\n      // The constructor isn't null or undefined at this point. Try\n      // to grab hold of its name.\n      var name = constructor.name;\n      // If the name is a non-empty string, we use that as the type\n      // name of this object. On Firefox, we often get 'Object' as\n      // the constructor name even for more specialized objects so\n      // we have to fall through to the toString() based implementation\n      // below in that case.\n      if (typeof(name) == 'string' && name && name != 'Object') return name;\n    }\n    var string = Object.prototype.toString.call(obj);\n    return string.substring(8, string.length - 1);\n  }\n\n  function chrome$typeNameOf() {\n    return this.constructor.name;\n  }\n\n  function firefox$typeNameOf() {\n    var name = constructorNameWithFallback(this);\n    if (name == 'Window') return 'DOMWindow';\n    if (name == 'Document') return 'HTMLDocument';\n    if (name == 'XMLDocument') return 'Document';\n    return name;\n  }\n\n  function ie$typeNameOf() {\n    var name = constructorNameWithFallback(this);\n    if (name == 'Window') return 'DOMWindow';\n    // IE calls both HTML and XML documents 'Document', so we check for the\n    // xmlVersion property, which is the empty string on HTML documents.\n    if (name == 'Document' && this.xmlVersion) return 'Document';\n    if (name == 'Document') return 'HTMLDocument';\n    return name;\n  }\n\n  // If we're not in the browser, we're almost certainly running on v8.\n  if (typeof(navigator) != 'object') return chrome$typeNameOf;\n\n  var userAgent = navigator.userAgent;\n  if (/Chrome/.test(userAgent)) return chrome$typeNameOf;\n  if (/Firefox/.test(userAgent)) return firefox$typeNameOf;\n  if (/MSIE/.test(userAgent)) return ie$typeNameOf;\n  return function() { return constructorNameWithFallback(this); };\n})());");
}
CoreJs.prototype.ensureInheritsHelper = function() {
  if (this._generatedInherits) return;
  this._generatedInherits = true;
  this.writer.writeln("/** Implements extends for Dart classes on JavaScript prototypes. */\nfunction $inherits(child, parent) {\n  if (child.prototype.__proto__) {\n    child.prototype.__proto__ = parent.prototype;\n  } else {\n    function tmp() {};\n    tmp.prototype = parent.prototype;\n    child.prototype = new tmp();\n    child.prototype.constructor = child;\n  }\n}");
}
CoreJs.prototype.ensureDefProp = function() {
  if (this._generatedDefProp) return;
  this._generatedDefProp = true;
  this.writer.writeln("function $defProp(obj, prop, value) {\n  Object.defineProperty(obj, prop,\n      {value: value, enumerable: false, writable: true, configurable: true});\n}");
}
CoreJs.prototype.ensureBind = function() {
  if (this._generatedBind) return;
  this._generatedBind = true;
  this.writer.writeln("Function.prototype.bind = Function.prototype.bind ||\n  function(thisObj) {\n    var func = this;\n    var funcLength = func.$length || func.length;\n    var argsLength = arguments.length;\n    if (argsLength > 1) {\n      var boundArgs = Array.prototype.slice.call(arguments, 1);\n      var bound = function() {\n        // Prepend the bound arguments to the current arguments.\n        var newArgs = Array.prototype.slice.call(arguments);\n        Array.prototype.unshift.apply(newArgs, boundArgs);\n        return func.apply(thisObj, newArgs);\n      };\n      bound.$length = Math.max(0, funcLength - (argsLength - 1));\n      return bound;\n    } else {\n      var bound = function() {\n        return func.apply(thisObj, arguments);\n      };\n      bound.$length = funcLength;\n      return bound;\n    }\n  };");
}
CoreJs.prototype.generate = function(w) {
  w.write(this.writer.get$text());
  this.writer = w;
  if (this.useNotNullBool) {
    this.useThrow = true;
    w.writeln("function $notnull_bool(test) {\n  if (test === true || test === false) return test;\n  $throw(new TypeError(test, 'bool'));\n}");
  }
  if (this.useThrow) {
    w.writeln("function $throw(e) {\n  // If e is not a value, we can use V8's captureStackTrace utility method.\n  // TODO(jmesserly): capture the stack trace on other JS engines.\n  if (e && (typeof e == 'object') && Error.captureStackTrace) {\n    // TODO(jmesserly): this will clobber the e.stack property\n    Error.captureStackTrace(e, $throw);\n  }\n  throw e;\n}");
  }
  if (this.useIndex) {
    this.markCorelibTypeUsed("NoSuchMethodException");
    this.ensureDefProp();
    w.writeln($globals.options.disableBoundsChecks ? "$defProp(Object.prototype, '$index', function(i) {\n  $throw(new NoSuchMethodException(this, \"operator []\", [i]));\n});\n$defProp(Array.prototype, '$index', function(i) {\n  return this[i];\n});\n$defProp(String.prototype, '$index', function(i) {\n  return this[i];\n});" : "$defProp(Object.prototype, '$index', function(i) {\n  $throw(new NoSuchMethodException(this, \"operator []\", [i]));\n});\n$defProp(Array.prototype, '$index', function(index) {\n  var i = index | 0;\n  if (i !== index) {\n    throw new IllegalArgumentException('index is not int');\n  } else if (i < 0 || i >= this.length) {\n    throw new IndexOutOfRangeException(index);\n  }\n  return this[i];\n});\n$defProp(String.prototype, '$index', function(i) {\n  return this[i];\n});");
  }
  if (this.useSetIndex) {
    this.markCorelibTypeUsed("NoSuchMethodException");
    this.ensureDefProp();
    w.writeln($globals.options.disableBoundsChecks ? "$defProp(Object.prototype, '$setindex', function(i, value) {\n  $throw(new NoSuchMethodException(this, \"operator []=\", [i, value]));\n});\n$defProp(Array.prototype, '$setindex',\n    function(i, value) { return this[i] = value; });" : "$defProp(Object.prototype, '$setindex', function(i, value) {\n  $throw(new NoSuchMethodException(this, \"operator []=\", [i, value]));\n});\n$defProp(Array.prototype, '$setindex', function(index, value) {\n  var i = index | 0;\n  if (i !== index) {\n    throw new IllegalArgumentException('index is not int');\n  } else if (i < 0 || i >= this.length) {\n    throw new IndexOutOfRangeException(index);\n  }\n  return this[i] = value;\n});");
  }
  if (!this.useIsolates) {
    if (this.useWrap0) {
      w.writeln("function $wrap_call$0(fn) { return fn; }");
    }
    if (this.useWrap1) {
      w.writeln("function $wrap_call$1(fn) { return fn; }");
    }
  }
  var $$list = orderValuesByKeys(this._usedOperators);
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var opImpl = $$i.next();
    w.writeln(opImpl);
  }
  if ($globals.world.dom != null) {
    this.ensureTypeNameOf();
    this.ensureDefProp();
    w.writeln("$defProp(Object.prototype, \"get$typeName\", Object.prototype.$typeNameOf);");
  }
}
// ********** Code for Element **************
function Element(name, _enclosingElement) {
  this.name = name;
  this._enclosingElement = _enclosingElement;
  if (null != this.name) {
    var mangled = this.mangleJsName();
    this._jsname = mangled;
  }
}
Element.prototype.get$name = function() { return this.name; };
Element.prototype.set$name = function(value) { return this.name = value; };
Element.prototype.set$_jsname = function(value) { return this._jsname = value; };
Element.prototype.get$library = function() {
  return null;
}
Element.prototype.get$span = function() {
  return null;
}
Element.prototype.get$isNative = function() {
  return false;
}
Element.prototype.hashCode = function() {
  return this.name.hashCode();
}
Element.prototype.get$jsname = function() {
  return this._jsname;
}
Element.prototype.get$nativeName = function() {
  return this._jsname;
}
Element.prototype.get$avoidNativeName = function() {
  return false;
}
Element.prototype.get$jsnamePriority = function() {
  return this.get$isNative() ? (2) : (this.get$library().get$isCore() ? (1) : (0));
}
Element.prototype.resolve = function() {

}
Element.prototype.mangleJsName = function() {
  return $globals.world.toJsIdentifier(this.name);
}
Element.prototype.get$typeParameters = function() {
  return null;
}
Element.prototype.get$typeArgsInOrder = function() {
  return const$0007;
}
Element.prototype.get$enclosingElement = function() {
  return this._enclosingElement == null ? this.get$library() : this._enclosingElement;
}
Element.prototype.set$enclosingElement = function(e) {
  var $0;
  return (this._enclosingElement = ($0 = e), $0);
}
Element.prototype.lookupTypeParam = function(name) {
  if (this.get$typeParameters() == null) return null;
  for (var i = (0);
   i < this.get$typeParameters().get$length(); i++) {
    if (this.get$typeParameters().$index(i).name == name) {
      return this.get$typeArgsInOrder().$index(i);
    }
  }
  return null;
}
Element.prototype.resolveType = function(node, typeErrors, allowTypeParams) {
  if (node == null) return $globals.world.varType;
  if ((node instanceof SimpleTypeReference)) {
    var ret = node.get$dynamic().get$type();
    if ($eq$(ret, $globals.world.voidType)) {
      $globals.world.error("\"void\" only allowed as return type", node.span);
      return $globals.world.varType;
    }
    return ret;
  }
  else if ((node instanceof NameTypeReference)) {
    var typeRef = node;
    var name;
    if (typeRef.names != null) {
      name = typeRef.names.last().name;
    }
    else {
      name = typeRef.name.name;
    }
    var typeParamType = this.lookupTypeParam(name);
    if ($ne$(typeParamType)) {
      if (!allowTypeParams) {
        $globals.world.error("using type parameter in illegal context.", node.span);
      }
      return typeParamType;
    }
    return this.get$enclosingElement().resolveType(node, typeErrors, allowTypeParams);
  }
  else if ((node instanceof GenericTypeReference)) {
    var typeRef = node;
    var baseType = this.resolveType(typeRef.baseType, typeErrors, allowTypeParams);
    if (!baseType.get$isGeneric()) {
      $globals.world.error(("" + baseType.get$name() + " is not generic"), typeRef.span);
      return $globals.world.varType;
    }
    if (typeRef.typeArguments.get$length() != baseType.get$typeParameters().get$length()) {
      $globals.world.error("wrong number of type arguments", typeRef.span);
      return $globals.world.varType;
    }
    var typeArgs = [];
    for (var i = (0);
     i < typeRef.typeArguments.get$length(); i++) {
      typeArgs.add(this.resolveType(typeRef.typeArguments.$index(i), typeErrors, allowTypeParams));
    }
    return baseType.getOrMakeConcreteType(typeArgs);
  }
  else if ((node instanceof FunctionTypeReference)) {
    var typeRef = node;
    var name = "";
    if (typeRef.func.name != null) {
      name = typeRef.func.name.name;
    }
    return this.get$library().getOrAddFunctionType(this, name, typeRef.func, null);
  }
  $globals.world.internalError("unexpected TypeReference", node.span);
}
// ********** Code for ExistingJsGlobal **************
$inherits(ExistingJsGlobal, Element);
function ExistingJsGlobal(name, declaringElement) {
  this.declaringElement = declaringElement;
  Element.call(this, name, null);
}
ExistingJsGlobal.prototype.get$isNative = function() {
  return true;
}
ExistingJsGlobal.prototype.get$jsnamePriority = function() {
  return (10);
}
ExistingJsGlobal.prototype.get$span = function() {
  return this.declaringElement.get$span();
}
ExistingJsGlobal.prototype.get$library = function() {
  return this.declaringElement.get$library();
}
// ********** Code for WorldGenerator **************
function WorldGenerator(main, writer) {
  this.main = main;
  this.hasStatics = false;
  this.corejs = new CoreJs();
  this.globals = new HashMapImplementation();
  this.writer = writer;
}
WorldGenerator.prototype.get$writer = function() { return this.writer; };
WorldGenerator.prototype.set$writer = function(value) { return this.writer = value; };
WorldGenerator.prototype.analyze = function() {
  var nlibs = (0), ntypes = (0), nmems = (0), nnews = (0);
  var $$list = $globals.world.libraries.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var lib = $$i.next();
    nlibs += (1);
    var $list0 = lib.get$types().getValues();
    for (var $i0 = $list0.iterator(); $i0.hasNext(); ) {
      var type = $i0.next();
      if (type.get$library().get$isDom() || type.get$isHiddenNativeType()) {
        if (type.get$isClass()) type.markUsed();
      }
      ntypes += (1);
      var allMembers = [];
      allMembers.addAll(type.get$constructors().getValues());
      allMembers.addAll(type.get$members().getValues());
      type.get$factories().forEach((function (allMembers, f) {
        return allMembers.add(f);
      }).bind(null, allMembers)
      );
      for (var $i1 = allMembers.iterator(); $i1.hasNext(); ) {
        var m = $i1.next();
        if (m.get$isAbstract() || !(m.get$isMethod() || m.get$isConstructor())) continue;
        m.get$methodData().analyze();
      }
    }
  }
}
WorldGenerator.prototype.run = function() {
  this.mainContext = new MethodGenerator(this.main, null);
  var mainTarget = new TypeValue(this.main.declaringType, this.main.get$span());
  var mainCall = this.main.invoke(this.mainContext, null, mainTarget, Arguments.get$EMPTY());
  this.main.declaringType.markUsed();
  if ($globals.options.compileAll) {
    this.markLibrariesUsed([$globals.world.coreimpl, $globals.world.corelib, this.main.declaringType.get$library()]);
  }
  $globals.world.numImplType.markUsed();
  $globals.world.stringImplType.markUsed();
  if (this.corejs.useIndex || this.corejs.useSetIndex) {
    if (!$globals.options.disableBoundsChecks) {
      this.markTypeUsed($globals.world.corelib.types.$index("IndexOutOfRangeException"));
      this.markTypeUsed($globals.world.corelib.types.$index("IllegalArgumentException"));
    }
  }
  if ($globals.world.isolatelib != null) {
    this.corejs.useIsolates = true;
    var isolateMain = $globals.world.isolatelib.lookup("startRootIsolate", this.main.get$span());
    mainCall = isolateMain.invoke(this.mainContext, null, new TypeValue($globals.world.isolatelib.topType, this.main.get$span()), new Arguments(null, [this.main._get(this.mainContext, this.main.definition, null)]));
  }
  this.writeTypes($globals.world.coreimpl);
  this.writeTypes($globals.world.corelib);
  this.writeTypes(this.main.declaringType.get$library());
  if (this._mixins != null) this.writer.write(this._mixins.get$text());
  this.writeDynamicDispatchMetadata();
  this.writeGlobals();
  this.writer.writeln(("" + mainCall.get$code() + ";"));
}
WorldGenerator.prototype.markLibrariesUsed = function(libs) {
  return this.getAllTypes(libs).forEach(this.get$markTypeUsed());
}
WorldGenerator.prototype.markTypeUsed = function(type) {
  if (!type.get$isClass()) return;
  type.markUsed();
  type.isTested = true;
  type.isTested = !type.get$isTop() && !(type.get$isNative() && type.get$members().getValues().every((function (m) {
    return m.get$isStatic() && !m.get$isFactory();
  })
  ));
  var members = ListFactory.ListFactory$from$factory(type.get$members().getValues());
  members.addAll(type.get$constructors().getValues());
  type.get$factories().forEach((function (f) {
    return members.add(f);
  })
  );
  for (var $$i = members.iterator(); $$i.hasNext(); ) {
    var member = $$i.next();
    if ((member instanceof PropertyMember)) {
      if (member.get$getter() != null) this.genMethod(member.get$getter());
      if (member.get$setter() != null) this.genMethod(member.get$setter());
    }
    if ((member instanceof MethodMember)) this.genMethod(member);
  }
}
WorldGenerator.prototype.get$markTypeUsed = function() {
  return this.markTypeUsed.bind(this);
}
WorldGenerator.prototype.getAllTypes = function(libs) {
  var types = [];
  var seen = new HashSetImplementation_Library();
  for (var $$i = libs.iterator(); $$i.hasNext(); ) {
    var mainLib = $$i.next();
    var toCheck = DoubleLinkedQueue.DoubleLinkedQueue$from$factory([mainLib]);
    while (!toCheck.isEmpty()) {
      var lib = toCheck.removeFirst();
      if (seen.contains(lib)) continue;
      seen.add(lib);
      lib.get$imports().forEach((function (lib, toCheck, i) {
        return toCheck.addLast(lib);
      }).bind(null, lib, toCheck)
      );
      lib.get$types().getValues().forEach((function (t) {
        return types.add(t);
      })
      );
    }
  }
  return types;
}
WorldGenerator.prototype.globalForStaticField = function(field, exp, dependencies) {
  this.hasStatics = true;
  var key = ("" + field.declaringType.get$jsname() + "." + field.get$jsname());
  var ret = this.globals.$index(key);
  if (null == ret) {
    ret = new GlobalValue(exp.get$type(), exp.get$code(), field.isFinal, field, null, exp, exp.span, dependencies);
    this.globals.$setindex(key, ret);
  }
  return ret;
}
WorldGenerator.prototype.globalForConst = function(exp, dependencies) {
  var key = $add$($add$(exp.get$type().get$jsname(), ":"), exp.get$code());
  var ret = this.globals.$index(key);
  if (null == ret) {
    var ns = this.globals.get$length().toString$0();
    while (ns.get$length() < (4)) ns = $add$("0", ns);
    var name = ("const$" + ns);
    ret = new GlobalValue(exp.get$type(), name, true, null, name, exp, exp.span, dependencies);
    this.globals.$setindex(key, ret);
  }
  return ret;
}
WorldGenerator.prototype.writeTypes = function(lib) {
  if (lib.isWritten) return;
  lib.isWritten = true;
  var $$list = lib.imports;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var import_ = $$i.next();
    this.writeTypes(import_.get$library());
  }
  for (var i = (0);
   i < lib.sources.get$length(); i++) {
    lib.sources.$index(i).orderInLibrary = i;
  }
  this.writer.comment(("//  ********** Library " + lib.name + " **************"));
  if (lib.get$isCore()) {
    this.writer.comment("//  ********** Natives dart:core **************");
    this.corejs.generate(this.writer);
  }
  var $$list = lib.natives;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var file = $$i.next();
    var filename = basename(file.get$filename());
    this.writer.comment(("//  ********** Natives " + filename + " **************"));
    this.writer.writeln(file.get$text());
  }
  lib.topType.markUsed();
  var orderedTypes = this._orderValues(lib.types);
  for (var $$i = orderedTypes.iterator(); $$i.hasNext(); ) {
    var type = $$i.next();
    if (type.get$isUsed() && type.get$isClass()) {
      this.writeType(type);
      if (type.get$isGeneric() && (null == type ? null != ($globals.world.listFactoryType) : type !== $globals.world.listFactoryType)) {
        var $$list = this._orderValues(type.get$_concreteTypes());
        for (var $i0 = $$list.iterator(); $i0.hasNext(); ) {
          var ct = $i0.next();
          if (ct.get$isUsed()) this.writeType(ct);
        }
      }
    }
    else if (type.get$isFunction() && type.get$varStubs().get$length() > (0)) {
      this.writer.comment(("// ********** Code for " + type.get$jsname() + " **************"));
      this._writeDynamicStubs(type);
    }
    if (type.get$typeCheckCode() != null) {
      this.writer.writeln(type.get$typeCheckCode());
    }
  }
}
WorldGenerator.prototype.genMethod = function(meth) {
  meth.get$methodData().run(meth);
}
WorldGenerator.prototype._prototypeOf = function(type, name) {
  if (type.get$isSingletonNative()) {
    return ("" + type.get$jsname() + "." + name);
  }
  else if (type.get$isHiddenNativeType()) {
    this.corejs.ensureDynamicProto();
    this._usedDynamicDispatchOnType(type);
    return ("$dynamic(\"" + name + "\")." + type.get$definition().get$nativeType().name);
  }
  else {
    return ("" + type.get$jsname() + ".prototype." + name);
  }
}
WorldGenerator.prototype._writePrototypePatch = function(type, name, functionBody, writer, isOneLiner) {
  var $0;
  var writeFunction = writer.get$writeln();
  var ending = ";";
  if (!isOneLiner) {
    writeFunction = writer.get$enterBlock();
    ending = "";
  }
  if (type.get$isObject()) {
    ($0 = $globals.world.counters).objectProtoMembers = $0.objectProtoMembers + (1);
  }
  if (type.get$isObject() || $eq$(type.get$genericType(), $globals.world.listFactoryType)) {
    if (isOneLiner) {
      ending = $add$(")", ending);
    }
    this.corejs.ensureDefProp();
    writeFunction.call$1(("$defProp(" + type.get$jsname() + ".prototype, \"" + name + "\", " + functionBody + ending));
    if (isOneLiner) return "}";
    return "});";
  }
  else {
    writeFunction.call$1($add$($add$($add$(this._prototypeOf(type, name), " = "), functionBody), ending));
    return isOneLiner ? "" : "}";
  }
}
WorldGenerator.prototype._maybeIsTest = function(onType, checkType) {
  var isSubtype = onType.isSubtypeOf(checkType);
  if (checkType.isTested) {
    this._writePrototypePatch(onType, ("is$" + checkType.get$jsname()), ("function(){return " + isSubtype + "}"), this.writer, true);
  }
  if (checkType.isChecked) {
    var body = "return this";
    var checkName = ("assert$" + checkType.get$jsname());
    if (!isSubtype) {
      body = $globals.world.objectType.varStubs.$index(checkName).get$body();
    }
    else if ($eq$(onType, $globals.world.stringImplType) || $eq$(onType, $globals.world.numImplType)) {
      body = ("return " + onType.get$nativeType().name + "(this)");
    }
    this._writePrototypePatch(onType, checkName, ("function(){" + body + "}"), this.writer, true);
  }
}
WorldGenerator.prototype.writeType = function(type) {
  var $0, $1;
  if (type.isWritten) return;
  type.isWritten = true;
  this.writeType(type.get$genericType());
  if (type.get$parent() != null) {
    this.writeType(type.get$parent());
  }
  var typeName = type.get$jsname() != null ? type.get$jsname() : "top level";
  this.writer.comment(("// ********** Code for " + typeName + " **************"));
  if (type.get$isNative() && !type.get$isTop() && !type.get$isConcreteGeneric()) {
    var nativeName = type.get$definition().get$nativeType().name;
    if ($eq$(nativeName, "")) {
      this.writer.writeln(("function " + type.get$jsname() + "() {}"));
    }
    else if (type.get$jsname() != nativeName) {
      if (type.get$isHiddenNativeType()) {
        if (this._hasStaticOrFactoryMethods(type)) {
          this.writer.writeln(("var " + type.get$jsname() + " = {};"));
        }
      }
      else {
        this.writer.writeln(("" + type.get$jsname() + " = " + nativeName + ";"));
      }
    }
  }
  if (!type.get$isTop()) {
    if ((($0 = type.get$genericType()) == null ? null != (type) : $0 !== type)) {
      this.corejs.ensureInheritsHelper();
      this.writer.writeln(("$inherits(" + type.get$jsname() + ", " + type.get$genericType().get$jsname() + ");"));
    }
    else if (!type.get$isNative()) {
      if (type.get$parent() != null && !type.get$parent().get$isObject()) {
        this.corejs.ensureInheritsHelper();
        this.writer.writeln(("$inherits(" + type.get$jsname() + ", " + type.get$parent().get$jsname() + ");"));
      }
    }
  }
  if (type.get$isTop()) {
  }
  else if (type.get$constructors().get$length() == (0)) {
    if (!type.get$isNative() || type.get$isConcreteGeneric()) {
      this.writer.writeln(("function " + type.get$jsname() + "() {}"));
    }
  }
  else {
    var wroteStandard = false;
    var $$list = type.get$constructors().getValues();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var c = $$i.next();
      if (c.get$methodData().writeDefinition(c, this.writer)) {
        if (c.get$isConstructor() && c.get$constructorName() == "") wroteStandard = true;
      }
    }
    if (!wroteStandard && (!type.get$isNative() || (($1 = type.get$genericType()) == null ? null != (type) : $1 !== type))) {
      this.writer.writeln(("function " + type.get$jsname() + "() {}"));
    }
  }
  if (!type.get$isConcreteGeneric()) {
    this._maybeIsTest(type, type);
  }
  if (type.get$genericType()._concreteTypes != null) {
    var $$list = this._orderValues(type.get$genericType()._concreteTypes);
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var ct = $$i.next();
      this._maybeIsTest(type, ct);
    }
  }
  if (type.get$interfaces() != null) {
    var seen = new HashSetImplementation();
    var worklist = [];
    worklist.addAll(type.get$interfaces());
    seen.addAll(type.get$interfaces());
    while (!worklist.isEmpty()) {
      var interface_ = worklist.removeLast();
      this._maybeIsTest(type, interface_.get$genericType());
      if (interface_.get$genericType()._concreteTypes != null) {
        var $$list = this._orderValues(interface_.get$genericType()._concreteTypes);
        for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
          var ct = $$i.next();
          this._maybeIsTest(type, ct);
        }
      }
      var $$list = interface_.get$interfaces();
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var other = $$i.next();
        if (!seen.contains$1(other)) {
          worklist.addLast(other);
          seen.add(other);
        }
      }
    }
  }
  type.get$factories().forEach(this.get$_writeMethod());
  var $$list = this._orderValues(type.get$members());
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var member = $$i.next();
    if ((member instanceof FieldMember)) {
      this._writeField(member);
    }
    if ((member instanceof PropertyMember)) {
      this._writeProperty(member);
    }
    if (member.get$isMethod()) {
      this._writeMethod(member);
    }
  }
  this._writeDynamicStubs(type);
}
WorldGenerator.prototype._hasStaticOrFactoryMethods = function(type) {
  return type.get$members().getValues().some((function (m) {
    return m.get$isMethod() && m.get$isStatic();
  })
  ) || !type.get$factories().isEmpty();
}
WorldGenerator.prototype._writeDynamicStubs = function(type) {
  var $$list = orderValuesByKeys(type.varStubs);
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var stub = $$i.next();
    if (!stub.get$isGenerated()) stub.generate(this.writer);
  }
}
WorldGenerator.prototype._writeStaticField = function(field) {
  if (field.isFinal) return;
  var fullname = ("" + field.declaringType.get$jsname() + "." + field.get$jsname());
  if (this.globals.containsKey(fullname)) {
    var value = this.globals.$index(fullname);
    if (field.declaringType.get$isTop() && !field.isNative) {
      this.writer.writeln(("$globals." + field.get$jsname() + " = " + value.get$exp().get$code() + ";"));
    }
    else {
      this.writer.writeln($add$(("$globals." + field.declaringType.get$jsname() + "_" + field.get$jsname()), (" = " + value.get$exp().get$code() + ";")));
    }
  }
}
WorldGenerator.prototype._writeField = function(field) {
  if (field.declaringType.get$isTop() && !field.isNative && field.value == null) {
    this.writer.writeln(("var " + field.get$jsname() + ";"));
  }
  if (field._provideGetter && !field.declaringType.get$isConcreteGeneric()) {
    this._writePrototypePatch(field.declaringType, ("get$" + field.get$jsname()), ("function() { return this." + field.get$jsname() + "; }"), this.writer, true);
  }
  if (field._provideSetter && !field.declaringType.get$isConcreteGeneric()) {
    this._writePrototypePatch(field.declaringType, ("set$" + field.get$jsname()), ("function(value) { return this." + field.get$jsname() + " = value; }"), this.writer, true);
  }
}
WorldGenerator.prototype._writeProperty = function(property) {
  if (property.getter != null) this._writeMethod(property.getter);
  if (property.setter != null) this._writeMethod(property.setter);
  if (property.get$needsFieldSyntax()) {
    this.writer.enterBlock($add$("Object.defineProperty(", ("" + property.declaringType.get$jsname() + ".prototype, \"" + property.get$jsname() + "\", {")));
    if (property.getter != null) {
      this.writer.write(("get: " + property.declaringType.get$jsname() + ".prototype." + property.getter.get$jsname()));
      this.writer.writeln(property.setter == null ? "" : ",");
    }
    if (property.setter != null) {
      this.writer.writeln(("set: " + property.declaringType.get$jsname() + ".prototype." + property.setter.get$jsname()));
    }
    this.writer.exitBlock("});");
  }
}
WorldGenerator.prototype._writeMethod = function(m) {
  m.get$methodData().writeDefinition(m, this.writer);
  if (m.get$isNative() && m._provideGetter) {
    if (MethodGenerator._maybeGenerateBoundGetter(m, this.writer)) {
      $globals.world.gen.corejs.ensureBind();
    }
  }
}
WorldGenerator.prototype.get$_writeMethod = function() {
  return this._writeMethod.bind(this);
}
WorldGenerator.prototype.writeGlobals = function() {
  if (this.globals.get$length() > (0)) {
    this.writer.comment("//  ********** Globals **************");
    var list = this.globals.getValues();
    list.sort((function (a, b) {
      return a.compareTo(b);
    })
    );
    this.writer.enterBlock("function $static_init(){");
    for (var $$i = list.iterator(); $$i.hasNext(); ) {
      var global = $$i.next();
      if (global.get$field() != null) {
        this._writeStaticField(global.get$field());
      }
    }
    this.writer.exitBlock("}");
    for (var $$i = list.iterator(); $$i.hasNext(); ) {
      var global = $$i.next();
      if (global.get$field() == null) {
        this.writer.writeln(("var " + global.get$name() + " = " + global.get$exp().get$code() + ";"));
      }
    }
  }
  if (!this.corejs.useIsolates) {
    if (this.hasStatics) {
      this.writer.writeln("var $globals = {};");
    }
    if (this.globals.get$length() > (0)) {
      this.writer.writeln("$static_init();");
    }
  }
}
WorldGenerator.prototype._usedDynamicDispatchOnType = function(type) {
  if (this.typesWithDynamicDispatch == null) this.typesWithDynamicDispatch = new HashSetImplementation();
  this.typesWithDynamicDispatch.add(type);
}
WorldGenerator.prototype.writeDynamicDispatchMetadata = function() {
  var $this = this; // closure support
  if (this.typesWithDynamicDispatch == null) return;
  this.writer.comment(("// " + this.typesWithDynamicDispatch.get$length() + " dynamic types."));
  var seen = new HashSetImplementation();
  var types = [];
  function visit(type) {
    if (seen.contains$1(type)) return;
    seen.add(type);
    var $$list = $this._orderCollectionValues(type.get$directSubtypes());
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var subtype = $$i.next();
      visit(subtype);
    }
    types.add(type);
  }
  var $$list = this._orderCollectionValues(this.typesWithDynamicDispatch);
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var type = $$i.next();
    visit(type);
  }
  var dispatchTypes = types.filter((function (type) {
    return !type.get$directSubtypes().isEmpty() && $this.typesWithDynamicDispatch.contains(type);
  })
  );
  this.writer.comment(("// " + types.get$length() + " types"));
  this.writer.comment(("// " + types.filter((function (t) {
    return !t.get$directSubtypes().isEmpty();
  })
  ).get$length() + " !leaf"));
  var varNames = [];
  var varDefns = new HashMapImplementation();
  var tagDefns = new HashMapImplementation();
  function makeExpression(type) {
    var expressions = [];
    var subtags = [type.get$nativeName()];
    function walk(type) {
      var $$list = $this._orderCollectionValues(type.get$directSubtypes());
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var subtype = $$i.next();
        var tag = subtype.get$nativeName();
        var existing = tagDefns.$index(tag);
        if ($eq$(existing)) {
          subtags.add(tag);
          walk(subtype);
        }
        else {
          if (varDefns.containsKey(existing)) {
            expressions.add(existing);
          }
          else {
            var varName = ("v" + varNames.get$length() + "/*" + tag + "*/");
            varNames.add(varName);
            varDefns.$setindex(varName, existing);
            tagDefns.$setindex(tag, varName);
            expressions.add(varName);
          }
        }
      }
    }
    walk(type);
    var constantPart = ("'" + Strings.join(subtags, "|") + "'");
    if ($ne$(constantPart, "''")) expressions.add(constantPart);
    var expression;
    if (expressions.get$length() == (1)) {
      expression = expressions.$index((0));
    }
    else {
      expression = ("[" + Strings.join(expressions, ",") + "].join('|')");
    }
    return expression;
  }
  for (var $$i = dispatchTypes.iterator(); $$i.hasNext(); ) {
    var type = $$i.next();
    tagDefns.$setindex(type.get$nativeName(), makeExpression(type));
  }
  if (!tagDefns.isEmpty()) {
    this.corejs.ensureDynamicSetMetadata();
    this.writer.enterBlock("(function(){");
    for (var $$i = varNames.iterator(); $$i.hasNext(); ) {
      var varName = $$i.next();
      this.writer.writeln(("var " + varName + " = " + varDefns.$index(varName) + ";"));
    }
    this.writer.enterBlock("var table = [");
    this.writer.comment("// [dynamic-dispatch-tag, tags of classes implementing dynamic-dispatch-tag]");
    var needsComma = false;
    for (var $$i = dispatchTypes.iterator(); $$i.hasNext(); ) {
      var type = $$i.next();
      if (needsComma) {
        this.writer.write(", ");
      }
      this.writer.writeln(("['" + type.get$nativeName() + "', " + tagDefns.$index(type.get$nativeName()) + "]"));
      needsComma = true;
    }
    this.writer.exitBlock("];");
    this.writer.writeln("$dynamicSetMetadata(table);");
    this.writer.exitBlock("})();");
  }
}
WorldGenerator.prototype._orderValues = function(map) {
  var values = map.getValues();
  values.sort(this.get$_compareMembers());
  return values;
}
WorldGenerator.prototype._orderCollectionValues = function(collection) {
  var values = ListFactory.ListFactory$from$factory(collection);
  values.sort(this.get$_compareMembers());
  return values;
}
WorldGenerator.prototype._compareMembers = function(x, y) {
  if (x.get$span() != null && y.get$span() != null) {
    var spans = x.get$span().compareTo(y.get$span());
    if (spans != (0)) return spans;
  }
  else {
    if (x.get$span() != null) return (-1);
    if (y.get$span() != null) return (1);
  }
  if ($eq$(x.get$name(), y.get$name())) return (0);
  if ($eq$(x.get$name())) return (-1);
  if ($eq$(y.get$name())) return (1);
  return x.get$name().compareTo(y.get$name());
}
WorldGenerator.prototype.get$_compareMembers = function() {
  return this._compareMembers.bind(this);
}
WorldGenerator.prototype.run$0 = WorldGenerator.prototype.run;
// ********** Code for MethodGenerator **************
function MethodGenerator(method, enclosingMethod) {
  this.enclosingMethod = enclosingMethod;
  this.needsThis = false;
  this.method = method;
  this.writer = new CodeWriter();
  if (this.enclosingMethod != null) {
    this._scope = new BlockScope(this, this.enclosingMethod._scope, this.method.get$definition(), false);
    this.captures = new HashSetImplementation();
  }
  else {
    this._scope = new BlockScope(this, null, this.method.get$definition(), false);
  }
  this._usedTemps = new HashSetImplementation();
  this._freeTemps = [];
  this.counters = $globals.world.counters;
}
MethodGenerator.prototype.get$method = function() { return this.method; };
MethodGenerator.prototype.get$writer = function() { return this.writer; };
MethodGenerator.prototype.set$writer = function(value) { return this.writer = value; };
MethodGenerator.prototype.get$_scope = function() { return this._scope; };
MethodGenerator.prototype.get$enclosingMethod = function() { return this.enclosingMethod; };
MethodGenerator.prototype.set$needsThis = function(value) { return this.needsThis = value; };
MethodGenerator.prototype.set$_paramCode = function(value) { return this._paramCode = value; };
MethodGenerator.prototype.get$counters = function() { return this.counters; };
MethodGenerator.prototype.get$library = function() {
  return this.method.get$library();
}
MethodGenerator.prototype.findMembers = function(name) {
  return this.get$library()._findMembers(name);
}
MethodGenerator.prototype.get$needsCode = function() {
  return true;
}
MethodGenerator.prototype.get$showWarnings = function() {
  return false;
}
MethodGenerator.prototype.get$isClosure = function() {
  return (this.enclosingMethod != null);
}
MethodGenerator.prototype.get$isStatic = function() {
  return this.method.get$isStatic();
}
MethodGenerator.prototype.getTemp = function(value) {
  return value.get$needsTemp() ? this.forceTemp(value) : value;
}
MethodGenerator.prototype.forceTemp = function(value) {
  var name;
  if (this._freeTemps.get$length() > (0)) {
    name = this._freeTemps.removeLast();
  }
  else {
    name = "$" + this._usedTemps.get$length();
  }
  this._usedTemps.add(name);
  return new VariableValue(value.get$staticType(), name, value.span, false, value);
}
MethodGenerator.prototype.assignTemp = function(tmp, v) {
  if ($eq$(tmp, v)) {
    return v;
  }
  else {
    return new Value(v.get$type(), ("(" + tmp.get$code() + " = " + v.get$code() + ")"), v.span);
  }
}
MethodGenerator.prototype.freeTemp = function(value) {

}
MethodGenerator.prototype.run = function() {
  var thisObject;
  if (this.method.get$isConstructor()) {
    thisObject = new ObjectValue(false, this.method.declaringType, this.method.get$span());
    thisObject.initFields();
  }
  else {
    thisObject = new Value(this.method.declaringType, "this", null);
  }
  var values = [];
  var $$list = this.method.get$parameters();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var p = $$i.next();
    values.add(new Value(p.get$type(), p.get$name(), null));
  }
  var args = new Arguments(null, values);
  this.evalBody(thisObject, args);
}
MethodGenerator.prototype.writeDefinition = function(defWriter, lambda) {
  var paramCode = this._paramCode;
  var names = null;
  if (this.captures != null && this.captures.get$length() > (0)) {
    names = ListFactory.ListFactory$from$factory(this.captures);
    names.sort((function (x, y) {
      return x.compareTo(y);
    })
    );
    paramCode = ListFactory.ListFactory$from$factory(names);
    paramCode.addAll(this._paramCode);
  }
  var _params = ("(" + Strings.join(this._paramCode, ", ") + ")");
  var params = ("(" + Strings.join(paramCode, ", ") + ")");
  var suffix = "}";
  if (this.method.declaringType.get$isTop() && !this.get$isClosure()) {
    defWriter.enterBlock(("function " + this.method.get$jsname() + params + " {"));
  }
  else if (this.get$isClosure()) {
    if (this.method.name == "") {
      defWriter.enterBlock(("(function " + params + " {"));
    }
    else if ($ne$(names)) {
      if (lambda == null) {
        defWriter.enterBlock(("var " + this.method.get$jsname() + " = (function" + params + " {"));
      }
      else {
        defWriter.enterBlock(("(function " + this.method.get$jsname() + params + " {"));
      }
    }
    else {
      defWriter.enterBlock(("function " + this.method.get$jsname() + params + " {"));
    }
  }
  else if (this.method.get$isConstructor()) {
    if (this.method.get$constructorName() == "") {
      defWriter.enterBlock(("function " + this.method.declaringType.get$jsname() + params + " {"));
    }
    else {
      defWriter.enterBlock(("" + this.method.declaringType.get$jsname() + "." + this.method.get$constructorName() + "$ctor = function" + params + " {"));
    }
  }
  else if (this.method.get$isFactory()) {
    defWriter.enterBlock(("" + this.method.get$generatedFactoryName() + " = function" + _params + " {"));
  }
  else if (this.method.get$isStatic()) {
    defWriter.enterBlock(("" + this.method.declaringType.get$jsname() + "." + this.method.get$jsname() + " = function" + _params + " {"));
  }
  else {
    suffix = $globals.world.gen._writePrototypePatch(this.method.declaringType, this.method.get$jsname(), ("function" + _params + " {"), defWriter, false);
  }
  if (this.needsThis) {
    defWriter.writeln("var $this = this; // closure support");
  }
  if (this._usedTemps.get$length() > (0) || this._freeTemps.get$length() > (0)) {
    this._freeTemps.addAll(this._usedTemps);
    this._freeTemps.sort((function (x, y) {
      return x.compareTo(y);
    })
    );
    defWriter.writeln(("var " + Strings.join(this._freeTemps, ", ") + ";"));
  }
  defWriter.writeln(this.writer.get$text());
  var usesBind = false;
  if ($ne$(names)) {
    usesBind = true;
    defWriter.exitBlock(("}).bind(null, " + Strings.join(names, ", ") + ")"));
  }
  else if (this.get$isClosure() && this.method.name == "") {
    defWriter.exitBlock("})");
  }
  else {
    defWriter.exitBlock(suffix);
  }
  if (this.method.get$isConstructor() && this.method.get$constructorName() != "") {
    defWriter.writeln($add$(("" + this.method.declaringType.get$jsname() + "." + this.method.get$constructorName() + "$ctor.prototype = "), ("" + this.method.declaringType.get$jsname() + ".prototype;")));
  }
  this._provideOptionalParamInfo(defWriter);
  if ((this.method instanceof MethodMember)) {
    if (MethodGenerator._maybeGenerateBoundGetter(this.method, defWriter)) {
      usesBind = true;
    }
  }
  if (usesBind) $globals.world.gen.corejs.ensureBind();
}
MethodGenerator._maybeGenerateBoundGetter = function(m, defWriter) {
  if (m._provideGetter) {
    var suffix = $globals.world.gen._writePrototypePatch(m.declaringType, $add$("get$", m.get$jsname()), "function() {", defWriter, false);
    defWriter.writeln(("return this." + m.get$jsname() + ".bind(this);"));
    defWriter.exitBlock(suffix);
    return true;
  }
  return false;
}
MethodGenerator.prototype._provideOptionalParamInfo = function(defWriter) {
  if ((this.method instanceof MethodMember)) {
    var meth = this.method;
    if (meth._provideOptionalParamInfo) {
      var optNames = [];
      var optValues = [];
      meth.genParameterValues(this);
      var $$list = meth.parameters;
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var param = $$i.next();
        if (param.get$isOptional()) {
          optNames.add(param.get$name());
          optValues.add(MethodGenerator._escapeString(param.get$value().get$code()));
        }
      }
      if (optNames.get$length() > (0)) {
        var start = "";
        if (meth.isStatic) {
          if (!meth.declaringType.get$isTop()) {
            start = $add$(meth.declaringType.get$jsname(), ".");
          }
        }
        else {
          start = $add$(meth.declaringType.get$jsname(), ".prototype.");
        }
        optNames.addAll(optValues);
        var optional = $add$($add$("['", Strings.join(optNames, "', '")), "']");
        defWriter.writeln(("" + start + meth.get$jsname() + ".$optional = " + optional));
      }
    }
  }
}
MethodGenerator.prototype._initField = function(newObject, name, value, span) {
  var field = this.method.declaringType.getMember(name);
  if ($eq$(field)) {
    $globals.world.error("bad initializer - no matching field", span);
  }
  if (!field.get$isField()) {
    $globals.world.error(("\"this." + name + "\" does not refer to a field"), span);
  }
  return newObject.setField(field, value, true);
}
MethodGenerator.prototype.evalBody = function(newObject, args) {
  var fieldsSet = false;
  if (this.method.get$isNative() && this.method.get$isConstructor() && (newObject instanceof ObjectValue)) {
    newObject.get$dynamic().set$seenNativeInitializer(true);
  }
  this._paramCode = [];
  for (var i = (0);
   i < this.method.get$parameters().get$length(); i++) {
    var p = this.method.get$parameters().$index(i);
    var currentArg = null;
    if (i < args.get$bareCount()) {
      currentArg = args.values.$index(i);
    }
    else {
      currentArg = args.getValue(p.get$name());
      if (null == currentArg) {
        p.genValue(this.method, this);
        currentArg = p.get$value();
        if (currentArg == null) {
          return;
        }
      }
    }
    if (p.get$isInitializer()) {
      this._paramCode.add(p.get$name());
      fieldsSet = true;
      this._initField(newObject, p.get$name(), currentArg, p.get$definition().get$span());
    }
    else {
      var paramValue = this._scope.declareParameter(p);
      this._paramCode.add(paramValue.get$code());
      if (newObject != null && newObject.get$isConst()) {
        this._scope.assign(p.get$name(), currentArg.convertTo(this, p.get$type()));
      }
    }
  }
  var initializerCall = null;
  var declaredInitializers = this.method.get$definition().get$dynamic().get$initializers();
  if ($ne$(declaredInitializers)) {
    for (var $$i = declaredInitializers.iterator(); $$i.hasNext(); ) {
      var init = $$i.next();
      if ((init instanceof CallExpression)) {
        if ($ne$(initializerCall)) {
          $globals.world.error("only one initializer redirecting call is allowed", init.get$span());
        }
        initializerCall = init;
      }
      else if ((init instanceof BinaryExpression) && TokenKind.kindFromAssign(init.get$op().kind) == (0)) {
        var left = init.get$x();
        if (!((left instanceof DotExpression) && (left.get$self() instanceof ThisExpression) || (left instanceof VarExpression))) {
          $globals.world.error("invalid left side of initializer", left.get$span());
          continue;
        }
        var initValue = this.visitValue(init.get$y());
        fieldsSet = true;
        this._initField(newObject, left.get$name().get$name(), initValue, left.get$span());
      }
      else {
        $globals.world.error("invalid initializer", init.get$span());
      }
    }
  }
  if (this.method.get$isConstructor() && $eq$(initializerCall) && !this.method.get$isNative()) {
    var parentType = this.method.declaringType.get$parent();
    if ($ne$(parentType) && !parentType.get$isObject()) {
      initializerCall = new CallExpression(new SuperExpression(this.method.get$span()), [], this.method.get$span());
    }
  }
  if (this.method.get$isConstructor() && (newObject instanceof ObjectValue)) {
    var fields = newObject.get$dynamic().get$fields();
    var $$list = fields.getKeys();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var field = $$i.next();
      var value = fields.$index(field);
      if (null != value) {
        this.writer.writeln(("this." + field.get$jsname() + " = " + value.get$code() + ";"));
      }
    }
  }
  if ($ne$(initializerCall)) {
    this.evalInitializerCall(newObject, initializerCall, fieldsSet);
  }
  if (this.method.get$isConstructor() && null != newObject && newObject.get$isConst()) {
    newObject.validateInitialized(this.method.get$span());
  }
  else if (this.method.get$isConstructor()) {
    var fields = newObject.get$dynamic().get$fields();
    var $$list = fields.getKeys();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var field = $$i.next();
      var value = fields.$index(field);
      if (null == value && field.get$isFinal() && $eq$(field.get$declaringType(), this.method.declaringType) && !newObject.get$dynamic().get$seenNativeInitializer()) {
        $globals.world.error(("uninitialized final field \"" + field.get$name() + "\""), field.get$span(), this.method.get$span());
      }
    }
  }
  var body = this.method.get$definition().get$dynamic().get$body();
  if (null == body) {
    if (!this.method.get$isConstructor() && !this.method.get$isNative()) {
      $globals.world.error(("unexpected empty body for " + this.method.name), this.method.get$definition().get$span());
    }
  }
  else {
    this.visitStatementsInBlock(body);
  }
}
MethodGenerator.prototype.evalInitializerCall = function(newObject, node, fieldsSet) {
  var contructorName = "";
  var targetExp = node.target;
  if ((targetExp instanceof DotExpression)) {
    var dot = targetExp;
    targetExp = dot.self;
    contructorName = dot.name.name;
  }
  var targetType = null;
  var target = null;
  if ((targetExp instanceof SuperExpression)) {
    targetType = this.method.declaringType.get$parent();
    target = this._makeSuperValue(targetExp);
  }
  else if ((targetExp instanceof ThisExpression)) {
    targetType = this.method.declaringType;
    target = this._makeThisValue(targetExp);
    if (fieldsSet) {
      $globals.world.error("no initialization allowed with redirecting constructor", node.span);
    }
  }
  else {
    $globals.world.error("bad call in initializers", node.span);
  }
  var m = targetType.getConstructor(contructorName);
  if ($eq$(m)) {
    $globals.world.error(("no matching constructor for " + targetType.name), node.span);
  }
  this.method.set$initDelegate(m);
  var other = m;
  while ($ne$(other)) {
    if ($eq$(other, this.method)) {
      $globals.world.error("initialization cycle", node.span);
      break;
    }
    other = other.get$initDelegate();
  }
  var newArgs = this._makeArgs(node.arguments);
  $globals.world.gen.genMethod(m);
  m._evalConstConstructor(newObject, newArgs);
  if (!newObject.isConst) {
    var value = m.invoke(this, node, target, newArgs);
    if ($ne$(target.get$type(), $globals.world.objectType)) {
      this.writer.writeln(("" + value.get$code() + ";"));
    }
  }
}
MethodGenerator.prototype._makeArgs = function(arguments) {
  var args = [];
  var seenLabel = false;
  for (var $$i = arguments.iterator(); $$i.hasNext(); ) {
    var arg = $$i.next();
    if (arg.get$label() != null) {
      seenLabel = true;
    }
    else if (seenLabel) {
      $globals.world.error("bare argument cannot follow named arguments", arg.get$span());
    }
    args.add(this.visitValue(arg.get$value()));
  }
  return new Arguments(arguments, args);
}
MethodGenerator.prototype._invokeNative = function(name, arguments) {
  var args = Arguments.get$EMPTY();
  if (arguments.get$length() > (0)) {
    args = new Arguments(null, arguments);
  }
  var method = $globals.world.corelib.topType.members.$index(name);
  return method.invoke(this, method.get$definition(), new Value($globals.world.corelib.topType, null, null), args);
}
MethodGenerator._escapeString = function(text) {
  return text.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"").replaceAll("\n", "\\n").replaceAll("\r", "\\r");
}
MethodGenerator.prototype.visitStatementsInBlock = function(body) {
  if ((body instanceof BlockStatement)) {
    var block = body;
    var $$list = block.body;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var stmt = $$i.next();
      stmt.visit(this);
    }
  }
  else {
    if (body != null) body.visit(this);
  }
  return false;
}
MethodGenerator.prototype._pushBlock = function(node, reentrant) {
  this._scope = new BlockScope(this, this._scope, node, reentrant);
}
MethodGenerator.prototype._popBlock = function(node) {
  var $0;
  if ((($0 = this._scope.node) == null ? null != (node) : $0 !== node)) {
    function spanOf(n) {
      return $ne$(n) ? n.get$span() : null;
    }
    $globals.world.internalError($add$(("scope mismatch. Trying to pop \"" + node + "\" but found "), (" \"" + this._scope.node + "\"")), spanOf(node), spanOf(this._scope.node));
  }
  this._scope = this._scope.parent;
}
MethodGenerator.prototype._visitLoop = function(node, visitBody) {
  if (this._scope.inferTypes) {
    this._loopFixedPoint(node, visitBody);
  }
  else {
    this._pushBlock(node, true);
    visitBody();
    this._popBlock(node);
  }
}
MethodGenerator.prototype._loopFixedPoint = function(node, visitBody) {
  var savedCounters = this.counters;
  var savedWriter = this.writer;
  var tries = (0);
  var startScope = this._scope.snapshot();
  var s = startScope;
  while (true) {
    this.writer = new CodeWriter();
    this.counters = new CounterLog();
    this._pushBlock(node, true);
    if (tries++ >= $globals.options.maxInferenceIterations) {
      this._scope.inferTypes = false;
    }
    visitBody();
    this._popBlock(node);
    if (!this._scope.inferTypes || !this._scope.unionWith(s)) {
      break;
    }
    s = this._scope.snapshot();
  }
  savedWriter.write$1(this.writer.get$text());
  this.writer = savedWriter;
  savedCounters.add(this.counters);
  this.counters = savedCounters;
}
MethodGenerator.prototype._makeLambdaMethod = function(name, func) {
  var meth = new MethodMember.lambda$ctor(name, this.method.declaringType, func);
  meth.set$enclosingElement(this.method);
  meth.set$_methodData(new MethodData(meth, this));
  meth.resolve();
  return meth;
}
MethodGenerator.prototype.visitBool = function(node) {
  return this.visitValue(node).convertTo(this, $globals.world.nonNullBool);
}
MethodGenerator.prototype.visitValue = function(node) {
  if (node == null) return null;
  var value = node.visit(this);
  value.checkFirstClass(node.span);
  return value;
}
MethodGenerator.prototype.visitTypedValue = function(node, expectedType) {
  var val = this.visitValue(node);
  return expectedType == null ? val : val.convertTo(this, expectedType);
}
MethodGenerator.prototype.visitVoid = function(node) {
  if ((node instanceof PostfixExpression)) {
    var value = this.visitPostfixExpression(node, true);
    value.checkFirstClass(node.span);
    return value;
  }
  else if ((node instanceof BinaryExpression)) {
    var value = this.visitBinaryExpression(node, true);
    value.checkFirstClass(node.span);
    return value;
  }
  return this.visitValue(node);
}
MethodGenerator.prototype.visitDietStatement = function(node) {
  var parser = new Parser(node.span.file, false, false, false, node.span.start);
  this.visitStatementsInBlock(parser.block());
  return false;
}
MethodGenerator.prototype.visitVariableDefinition = function(node) {
  var isFinal = false;
  if (node.modifiers != null && node.modifiers.$index((0)).kind == (99)) {
    isFinal = true;
  }
  this.writer.write("var ");
  var type = this.method.resolveType(node.type, false, true);
  for (var i = (0);
   i < node.names.get$length(); i++) {
    if (i > (0)) {
      this.writer.write(", ");
    }
    var name = node.names.$index(i).name;
    var value = this.visitValue(node.values.$index(i));
    if (isFinal && $eq$(value)) {
      $globals.world.error("no value specified for final variable", node.span);
    }
    var val = this._scope.create(name, type, node.names.$index(i).span, isFinal, false);
    if ($eq$(value)) {
      if (this._scope.reentrant) {
        this.writer.write(("" + val.get$code() + " = null"));
      }
      else {
        this.writer.write(("" + val.get$code()));
      }
    }
    else {
      value = value.convertTo(this, type);
      this._scope.inferAssign(name, value);
      this.writer.write(("" + val.get$code() + " = " + value.get$code()));
    }
  }
  this.writer.writeln(";");
  return false;
}
MethodGenerator.prototype.visitFunctionDefinition = function(node) {
  var meth = this._makeLambdaMethod(node.name.name, node);
  var funcValue = this._scope.create(meth.get$name(), meth.get$functionType(), this.method.get$definition().get$span(), true, false);
  meth.get$methodData().createFunction(this.writer);
  return false;
}
MethodGenerator.prototype.visitReturnStatement = function(node) {
  if (node.value == null) {
    this.writer.writeln("return;");
  }
  else {
    if (this.method.get$isConstructor()) {
      $globals.world.error("return of value not allowed from constructor", node.span);
    }
    var value = this.visitTypedValue(node.value, this.method.get$returnType());
    this.writer.writeln(("return " + value.get$code() + ";"));
  }
  return true;
}
MethodGenerator.prototype.visitThrowStatement = function(node) {
  if (node.value != null) {
    var value = this.visitValue(node.value);
    value.invoke(this, "toString", node, Arguments.get$EMPTY());
    this.writer.writeln(("$throw(" + value.get$code() + ");"));
    $globals.world.gen.corejs.useThrow = true;
  }
  else {
    var rethrow = this._scope.getRethrow();
    if ($eq$(rethrow)) {
      $globals.world.error("rethrow outside of catch", node.span);
    }
    else {
      this.writer.writeln(("throw " + rethrow + ";"));
    }
  }
  return true;
}
MethodGenerator.prototype.visitAssertStatement = function(node) {
  var test = this.visitValue(node.test);
  if ($globals.options.enableAsserts) {
    var span = node.test.span;
    var line = span.get$file().getLine(span.get$start()) + (1);
    var column = span.get$file().getColumn($sub$(line, (1)), span.get$start()) + (1);
    var args = [test, Value.fromString(span.get$text(), node.span), Value.fromString(span.get$file().filename, node.span), Value.fromInt(line, node.span), Value.fromInt(column, node.span)];
    var tp = $globals.world.corelib.topType;
    var f = tp.getMember("_assert");
    var value = f.invoke(this, node, new TypeValue(tp, null), new Arguments(null, args));
    this.writer.writeln(("" + value.get$code() + ";"));
  }
  return false;
}
MethodGenerator.prototype.visitBreakStatement = function(node) {
  if (node.label == null) {
    this.writer.writeln("break;");
  }
  else {
    this.writer.writeln(("break " + node.label.name + ";"));
  }
  return true;
}
MethodGenerator.prototype.visitContinueStatement = function(node) {
  if (node.label == null) {
    this.writer.writeln("continue;");
  }
  else {
    this.writer.writeln(("continue " + node.label.name + ";"));
  }
  return true;
}
MethodGenerator.prototype.visitIfStatement = function(node) {
  var test = this.visitBool(node.test);
  this.writer.write(("if (" + test.get$code() + ") "));
  var exit1 = node.trueBranch.visit(this);
  if (node.falseBranch != null) {
    this.writer.write("else ");
    if (node.falseBranch.visit(this) && exit1) {
      return true;
    }
  }
  return false;
}
MethodGenerator.prototype.visitWhileStatement = function(node) {
  var $this = this; // closure support
  var test = this.visitBool(node.test);
  this.writer.write(("while (" + test.get$code() + ") "));
  this._visitLoop(node, (function () {
    node.body.visit($this);
  })
  );
  return false;
}
MethodGenerator.prototype.visitDoStatement = function(node) {
  var $this = this; // closure support
  this.writer.write("do ");
  this._visitLoop(node, (function () {
    node.body.visit($this);
  })
  );
  var test = this.visitBool(node.test);
  this.writer.writeln(("while (" + test.get$code() + ")"));
  return false;
}
MethodGenerator.prototype.visitForStatement = function(node) {
  var $this = this; // closure support
  this._pushBlock(node, false);
  this.writer.write("for (");
  if (node.init != null) {
    node.init.visit(this);
  }
  else {
    this.writer.write(";");
  }
  this._visitLoop(node, (function () {
    if (node.test != null) {
      var test = $this.visitBool(node.test);
      $this.writer.write((" " + test.get$code() + "; "));
    }
    else {
      $this.writer.write("; ");
    }
    var needsComma = false;
    var $$list = node.step;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var s = $$i.next();
      if (needsComma) $this.writer.write(", ");
      var sv = $this.visitVoid(s);
      $this.writer.write(sv.get$code());
      needsComma = true;
    }
    $this.writer.write(") ");
    $this._pushBlock(node.body, false);
    node.body.visit($this);
    $this._popBlock(node.body);
  })
  );
  this._popBlock(node);
  return false;
}
MethodGenerator.prototype.visitForInStatement = function(node) {
  var $this = this; // closure support
  var itemType = this.method.resolveType(node.item.type, false, true);
  var list = node.list.visit(this);
  this._visitLoop(node, (function () {
    $this._visitForInBody(node, itemType, list);
  })
  );
  return false;
}
MethodGenerator.prototype._visitForInBody = function(node, itemType, list) {
  var isFinal = node.item.isFinal;
  var itemName = node.item.name.name;
  var item = this._scope.create(itemName, itemType, node.item.name.span, isFinal, false);
  if (list.get$needsTemp()) {
    var listVar = this._scope.create("$list", list.get$type(), null, false, false);
    this.writer.writeln(("var " + listVar.get$code() + " = " + list.get$code() + ";"));
    list = listVar;
  }
  if ($eq$(list.get$type().get$genericType(), $globals.world.listFactoryType)) {
    var tmpi = this._scope.create("$i", $globals.world.numType, null, false, false);
    var listLength = list.get_(this, "length", node.list);
    this.writer.enterBlock($add$(("for (var " + tmpi.get$code() + " = 0;"), ("" + tmpi.get$code() + " < " + listLength.get$code() + "; " + tmpi.get$code() + "++) {")));
    var value = list.invoke(this, ":index", node.list, new Arguments(null, [tmpi]));
    this.writer.writeln(("var " + item.get$code() + " = " + value.get$code() + ";"));
  }
  else {
    var iterator = list.invoke(this, "iterator", node.list, Arguments.get$EMPTY());
    var tmpi = this._scope.create("$i", iterator.get$type(), null, false, false);
    var hasNext = tmpi.invoke(this, "hasNext", node.list, Arguments.get$EMPTY());
    var next = tmpi.invoke(this, "next", node.list, Arguments.get$EMPTY());
    this.writer.enterBlock(("for (var " + tmpi.get$code() + " = " + iterator.get$code() + "; " + hasNext.get$code() + "; ) {"));
    this.writer.writeln(("var " + item.get$code() + " = " + next.get$code() + ";"));
  }
  this.visitStatementsInBlock(node.body);
  this.writer.exitBlock("}");
}
MethodGenerator.prototype._genToDartException = function(ex) {
  var result = this._invokeNative("_toDartException", [ex]);
  this.writer.writeln(("" + ex.get$code() + " = " + result.get$code() + ";"));
}
MethodGenerator.prototype._genStackTraceOf = function(trace, ex) {
  var result = this._invokeNative("_stackTraceOf", [ex]);
  this.writer.writeln(("var " + trace.get$code() + " = " + result.get$code() + ";"));
}
MethodGenerator.prototype.visitTryStatement = function(node) {
  this.writer.enterBlock("try {");
  this._pushBlock(node.body, false);
  this.visitStatementsInBlock(node.body);
  this._popBlock(node.body);
  if (node.catches.get$length() == (1)) {
    var catch_ = node.catches.$index((0));
    this._pushBlock(catch_, false);
    var exType = this.method.resolveType(catch_.get$exception().get$type(), false, true);
    var ex = this._scope.declare(catch_.get$exception());
    this._scope.rethrow = ex.get$code();
    this.writer.nextBlock(("} catch (" + ex.get$code() + ") {"));
    if ($ne$(catch_.get$trace())) {
      var trace = this._scope.declare(catch_.get$trace());
      this._genStackTraceOf(trace, ex);
    }
    this._genToDartException(ex);
    if (!exType.get$isVarOrObject()) {
      var test = ex.instanceOf$3$isTrue$forceCheck(this, exType, catch_.get$exception().get$span(), false, true);
      this.writer.writeln(("if (" + test.get$code() + ") throw " + ex.get$code() + ";"));
    }
    this.visitStatementsInBlock(node.catches.$index((0)).body);
    this._popBlock(catch_);
  }
  else if (node.catches.get$length() > (0)) {
    this._pushBlock(node, false);
    var ex = this._scope.create("$ex", $globals.world.varType, null, false, false);
    this._scope.rethrow = ex.get$code();
    this.writer.nextBlock(("} catch (" + ex.get$code() + ") {"));
    var trace = null;
    if (node.catches.some((function (c) {
      return $ne$(c.get$trace());
    })
    )) {
      trace = this._scope.create("$trace", $globals.world.varType, null, false, false);
      this._genStackTraceOf(trace, ex);
    }
    this._genToDartException(ex);
    var needsRethrow = true;
    for (var i = (0);
     i < node.catches.get$length(); i++) {
      var catch_ = node.catches.$index(i);
      this._pushBlock(catch_, false);
      var tmpType = this.method.resolveType(catch_.get$exception().get$type(), false, true);
      var tmp = this._scope.declare(catch_.get$exception());
      if (!tmpType.get$isVarOrObject()) {
        var test = ex.instanceOf$3$isTrue$forceCheck(this, tmpType, catch_.get$exception().get$span(), true, true);
        if (i == (0)) {
          this.writer.enterBlock(("if (" + test.get$code() + ") {"));
        }
        else {
          this.writer.nextBlock(("} else if (" + test.get$code() + ") {"));
        }
      }
      else if (i > (0)) {
        this.writer.nextBlock("} else {");
      }
      this.writer.writeln(("var " + tmp.get$code() + " = " + ex.get$code() + ";"));
      if ($ne$(catch_.get$trace())) {
        var tmptrace = this._scope.declare(catch_.get$trace());
        this.writer.writeln(("var " + tmptrace.get$code() + " = " + trace.get$code() + ";"));
      }
      this.visitStatementsInBlock(catch_.get$body());
      this._popBlock(catch_);
      if (tmpType.get$isVarOrObject()) {
        if (i + (1) < node.catches.get$length()) {
          $globals.world.error("Unreachable catch clause", node.catches.$index(i + (1)).span);
        }
        if (i > (0)) {
          this.writer.exitBlock("}");
        }
        needsRethrow = false;
        break;
      }
    }
    if (needsRethrow) {
      this.writer.nextBlock("} else {");
      this.writer.writeln(("throw " + ex.get$code() + ";"));
      this.writer.exitBlock("}");
    }
    this._popBlock(node);
  }
  if (node.finallyBlock != null) {
    this.writer.nextBlock("} finally {");
    this._pushBlock(node.finallyBlock, false);
    this.visitStatementsInBlock(node.finallyBlock);
    this._popBlock(node.finallyBlock);
  }
  this.writer.exitBlock("}");
  return false;
}
MethodGenerator.prototype.visitSwitchStatement = function(node) {
  var test = this.visitValue(node.test);
  this.writer.enterBlock(("switch (" + test.get$code() + ") {"));
  var $$list = node.cases;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var case_ = $$i.next();
    if (case_.get$label() != null) {
      $globals.world.error("unimplemented: labeled case statement", case_.get$span());
    }
    this._pushBlock(case_, false);
    for (var i = (0);
     i < case_.get$cases().get$length(); i++) {
      var expr = case_.get$cases().$index(i);
      if ($eq$(expr)) {
        if (i < case_.get$cases().get$length() - (1)) {
          $globals.world.error("default clause must be the last case", case_.get$span());
        }
        this.writer.writeln("default:");
      }
      else {
        var value = this.visitValue(expr);
        this.writer.writeln(("case " + value.get$code() + ":"));
      }
    }
    this.writer.enterBlock("");
    var caseExits = this._visitAllStatements(case_.get$statements(), false);
    if ($ne$(case_, node.cases.$index(node.cases.get$length() - (1))) && !caseExits) {
      var span = case_.get$statements().$index(case_.get$statements().get$length() - (1)).get$span();
      this.writer.writeln("$throw(new FallThroughError());");
      $globals.world.gen.corejs.useThrow = true;
    }
    this.writer.exitBlock("");
    this._popBlock(case_);
  }
  this.writer.exitBlock("}");
  return false;
}
MethodGenerator.prototype._visitAllStatements = function(statementList, exits) {
  for (var i = (0);
   i < statementList.get$length(); i++) {
    var stmt = statementList.$index(i);
    exits = stmt.visit(this);
    if ($ne$(stmt, statementList.$index(statementList.get$length() - (1))) && exits) {
      $globals.world.warning("unreachable code", statementList.$index(i + (1)).get$span());
    }
  }
  return exits;
}
MethodGenerator.prototype.visitBlockStatement = function(node) {
  this._pushBlock(node, false);
  this.writer.enterBlock("{");
  var exits = this._visitAllStatements(node.body, false);
  this.writer.exitBlock("}");
  this._popBlock(node);
  return exits;
}
MethodGenerator.prototype.visitLabeledStatement = function(node) {
  this.writer.writeln(("" + node.name.name + ":"));
  node.body.visit(this);
  return false;
}
MethodGenerator.prototype.visitExpressionStatement = function(node) {
  if ((node.body instanceof VarExpression) || (node.body instanceof ThisExpression)) {
    $globals.world.warning("variable used as statement", node.span);
  }
  var value = this.visitVoid(node.body);
  this.writer.writeln(("" + value.get$code() + ";"));
  return false;
}
MethodGenerator.prototype.visitEmptyStatement = function(node) {
  this.writer.writeln(";");
  return false;
}
MethodGenerator.prototype._checkNonStatic = function(node) {
  if (this.get$isStatic()) {
    $globals.world.warning("not allowed in static method", node.span);
  }
}
MethodGenerator.prototype._makeSuperValue = function(node) {
  var parentType = this.method.declaringType.get$parent();
  this._checkNonStatic(node);
  if ($eq$(parentType)) {
    $globals.world.error("no super class", node.span);
  }
  return new SuperValue(parentType, node.span);
}
MethodGenerator.prototype._getOutermostMethod = function() {
  var result = this;
  while (result.get$enclosingMethod() != null) {
    result = result.get$enclosingMethod();
  }
  return result;
}
MethodGenerator.prototype._makeThisCode = function() {
  if (this.enclosingMethod != null) {
    this._getOutermostMethod().set$needsThis(true);
    return "$this";
  }
  else {
    return "this";
  }
}
MethodGenerator.prototype._makeThisValue = function(node) {
  if (this.enclosingMethod != null) {
    var outermostMethod = this._getOutermostMethod();
    outermostMethod._checkNonStatic(node);
    outermostMethod.set$needsThis(true);
    return new ThisValue(outermostMethod.get$method().get$declaringType(), "$this", node != null ? node.span : null);
  }
  else {
    this._checkNonStatic(node);
    return new ThisValue(this.method.declaringType, "this", node != null ? node.span : null);
  }
}
MethodGenerator.prototype.visitLambdaExpression = function(node) {
  var name = (node.func.name != null) ? node.func.name.name : "";
  var meth = this._makeLambdaMethod(name, node.func);
  return meth.get$methodData().createLambda(node, this);
}
MethodGenerator.prototype.visitCallExpression = function(node) {
  var target;
  var position = node.target;
  var name = ":call";
  if ((node.target instanceof DotExpression)) {
    var dot = node.target;
    target = dot.self.visit(this);
    name = dot.name.name;
    position = dot.name;
  }
  else if ((node.target instanceof VarExpression)) {
    var varExpr = node.target;
    name = varExpr.name.name;
    target = this._scope.lookup(name);
    if ($ne$(target)) {
      return target.invoke(this, ":call", node, this._makeArgs(node.arguments));
    }
    target = this._makeThisOrType(varExpr.span);
    return target.invoke(this, name, node, this._makeArgs(node.arguments));
  }
  else {
    target = node.target.visit(this);
  }
  return target.invoke(this, name, position, this._makeArgs(node.arguments));
}
MethodGenerator.prototype.visitIndexExpression = function(node) {
  var target = this.visitValue(node.target);
  var index = this.visitValue(node.index);
  return target.invoke(this, ":index", node, new Arguments(null, [index]));
}
MethodGenerator.prototype._expressionNeedsParens = function(e) {
  return ((e instanceof BinaryExpression) || (e instanceof ConditionalExpression) || (e instanceof PostfixExpression) || this._isUnaryIncrement(e));
}
MethodGenerator.prototype.visitBinaryExpression = function(node, isVoid) {
  var kind = node.op.kind;
  if ($eq$(kind, (35)) || $eq$(kind, (34))) {
    var x = this.visitTypedValue(node.x, $globals.world.nonNullBool);
    var y = this.visitTypedValue(node.y, $globals.world.nonNullBool);
    return x.binop(kind, y, this, node);
  }
  else if ($eq$(kind, (50)) || $eq$(kind, (51))) {
    var x = this.visitValue(node.x);
    var y = this.visitValue(node.y);
    return x.binop(kind, y, this, node);
  }
  var assignKind = TokenKind.kindFromAssign(node.op.kind);
  if ($eq$(assignKind, (-1))) {
    var x = this.visitValue(node.x);
    var y = this.visitValue(node.y);
    return x.binop(kind, y, this, node);
  }
  else if (($ne$(assignKind, (0))) && this._expressionNeedsParens(node.y)) {
    return this._visitAssign(assignKind, node.x, new ParenExpression(node.y, node.y.span), node, isVoid ? (1) : (2));
  }
  else {
    return this._visitAssign(assignKind, node.x, node.y, node, isVoid ? (1) : (2));
  }
}
MethodGenerator.prototype._visitAssign = function(kind, xn, yn, position, returnKind) {
  if ((xn instanceof VarExpression)) {
    return this._visitVarAssign(kind, xn, yn, position, returnKind);
  }
  else if ((xn instanceof IndexExpression)) {
    return this._visitIndexAssign(kind, xn, yn, position, returnKind);
  }
  else if ((xn instanceof DotExpression)) {
    return this._visitDotAssign(kind, xn, yn, position, returnKind);
  }
  else {
    $globals.world.error("illegal lhs", xn.span);
  }
}
MethodGenerator.prototype._visitVarAssign = function(kind, xn, yn, position, returnKind) {
  var name = xn.name.name;
  var x = this._scope.lookup(name);
  var y = this.visitValue(yn);
  if ($ne$(x)) {
    y = y.convertTo(this, x.get$staticType());
    this._scope.inferAssign(name, Value.union(x, y));
    if (x.get$isFinal()) {
      $globals.world.error(("final variable \"" + x.get$code() + "\" is not assignable"), position.span);
    }
    if (kind == (0)) {
      return new Value(y.get$type(), ("" + x.get$code() + " = " + y.get$code()), position.span);
    }
    else if (x.get$type().get$isNum() && y.get$type().get$isNum() && (kind != (46))) {
      if (returnKind == (3)) {
        $globals.world.internalError("should not be here", position.span);
      }
      var op = TokenKind.kindToString(kind);
      return new Value(y.get$type(), ("" + x.get$code() + " " + op + "= " + y.get$code()), position.span);
    }
    else {
      var right = x;
      y = right.binop(kind, y, this, position);
      if (returnKind == (3)) {
        var tmp = this.forceTemp(x);
        var ret = new Value(x.get$type(), ("(" + tmp.get$code() + " = " + x.get$code() + ", " + x.get$code() + " = " + y.get$code() + ", " + tmp.get$code() + ")"), position.span);
        this.freeTemp(tmp);
        return ret;
      }
      else {
        return new Value(x.get$type(), ("" + x.get$code() + " = " + y.get$code()), position.span);
      }
    }
  }
  else {
    x = this._makeThisOrType(position.span);
    return x.set_$4$kind$returnKind(this, name, position, y, kind, returnKind);
  }
}
MethodGenerator.prototype._visitIndexAssign = function(kind, xn, yn, position, returnKind) {
  var target = this.visitValue(xn.target);
  var index = this.visitValue(xn.index);
  var y = this.visitValue(yn);
  return target.setIndex$4$kind$returnKind(this, index, position, y, kind, returnKind);
}
MethodGenerator.prototype._visitDotAssign = function(kind, xn, yn, position, returnKind) {
  var target = xn.self.visit(this);
  var y = this.visitValue(yn);
  return target.set_$4$kind$returnKind(this, xn.name.name, xn.name, y, kind, returnKind);
}
MethodGenerator.prototype.visitUnaryExpression = function(node) {
  var value = this.visitValue(node.self);
  switch (node.op.kind) {
    case (16):
    case (17):

      if (value.get$type().get$isNum() && !value.get$isFinal() && (node.self instanceof VarExpression)) {
        return new Value(value.get$type(), ("" + node.op + value.get$code()), node.span);
      }
      else {
        var kind = ((16) == node.op.kind ? (42) : (43));
        var operand = new LiteralExpression(Value.fromInt((1), node.span), node.span);
        var assignValue = this._visitAssign(kind, node.self, operand, node, (2));
        return new Value(assignValue.get$type(), ("(" + assignValue.get$code() + ")"), node.span);
      }

  }
  return value.unop(node.op.kind, this, node);
}
MethodGenerator.prototype.visitDeclaredIdentifier = function(node) {
  $globals.world.error("Expected expression", node.span);
}
MethodGenerator.prototype.visitAwaitExpression = function(node) {
  $globals.world.internalError("Await expressions should have been eliminated before code generation", node.span);
}
MethodGenerator.prototype.visitPostfixExpression = function(node, isVoid) {
  var value = this.visitValue(node.body);
  if (value.get$type().get$isNum() && !value.get$isFinal() && (node.body instanceof VarExpression)) {
    return new Value(value.get$type(), ("" + value.get$code() + node.op), node.span);
  }
  var kind = ((16) == node.op.kind) ? (42) : (43);
  var operand = new LiteralExpression(Value.fromInt((1), node.span), node.span);
  var ret = this._visitAssign(kind, node.body, operand, node, isVoid ? (1) : (3));
  return ret;
}
MethodGenerator.prototype.visitNewExpression = function(node) {
  var typeRef = node.type;
  var constructorName = "";
  if (node.name != null) {
    constructorName = node.name.name;
  }
  if ($eq$(constructorName, "") && (typeRef instanceof NameTypeReference) && typeRef.get$names() != null) {
    var names = ListFactory.ListFactory$from$factory(typeRef.get$names());
    constructorName = names.removeLast().get$name();
    if (names.get$length() == (0)) names = null;
    typeRef = new NameTypeReference(typeRef.get$isFinal(), typeRef.get$name(), names, typeRef.get$span());
  }
  var type = this.method.resolveType(typeRef, true, true);
  if (type.get$isTop()) {
    type = type.get$library().findTypeByName(constructorName);
    constructorName = "";
  }
  if ((type instanceof ParameterType)) {
    $globals.world.error("cannot instantiate a type parameter", node.span);
    return this._makeMissingValue(constructorName);
  }
  var m = type.getConstructor(constructorName);
  if ($eq$(m)) {
    var name = type.get$jsname();
    if (type.get$isVar()) {
      name = typeRef.get$name().get$name();
    }
    $globals.world.error(("no matching constructor for " + name), node.span);
    return this._makeMissingValue(name);
  }
  if (node.isConst) {
    if (!m.get$isConst()) {
      $globals.world.error("can't use const on a non-const constructor", node.span);
    }
    var $$list = node.arguments;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var arg = $$i.next();
      if (!this.visitValue(arg.get$value()).get$isConst()) {
        $globals.world.error("const constructor expects const arguments", arg.get$span());
      }
    }
  }
  var target = new TypeValue(type, typeRef.get$span());
  return m.invoke(this, node, target, this._makeArgs(node.arguments));
}
MethodGenerator.prototype.visitListExpression = function(node) {
  var argValues = [];
  var listType = $globals.world.listType;
  var type = $globals.world.varType;
  if (node.itemType != null) {
    type = this.method.resolveType(node.itemType, true, !node.isConst);
    if (node.isConst && ((type instanceof ParameterType) || type.get$hasTypeParams())) {
      $globals.world.error("type parameter cannot be used in const list literals");
    }
    listType = listType.getOrMakeConcreteType([type]);
  }
  var $$list = node.values;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var item = $$i.next();
    var arg = this.visitTypedValue(item, type);
    argValues.add(arg);
    if (node.isConst && !arg.get$isConst()) {
      $globals.world.error("const list can only contain const values", arg.get$span());
    }
  }
  $globals.world.listFactoryType.markUsed();
  var ret = new ListValue(argValues, node.isConst, listType, node.span);
  if (ret.get$isConst()) return ret.getGlobalValue();
  return ret;
}
MethodGenerator.prototype.visitMapExpression = function(node) {
  if (node.items.get$length() == (0) && !node.isConst) {
    return $globals.world.mapType.getConstructor("").invoke(this, node, new TypeValue($globals.world.mapType, node.span), Arguments.get$EMPTY());
  }
  var values = [];
  var valueType = $globals.world.varType, keyType = $globals.world.stringType;
  var mapType = $globals.world.mapType;
  if (null != node.valueType) {
    if (null != node.keyType) {
      keyType = this.method.resolveType(node.keyType, true, !node.isConst);
      if (!keyType.get$isString()) {
        $globals.world.error("the key type of a map literal must be \"String\"", keyType.get$span());
      }
      if (node.isConst && ((keyType instanceof ParameterType) || keyType.get$hasTypeParams())) {
        $globals.world.error("type parameter cannot be used in const map literals");
      }
    }
    valueType = this.method.resolveType(node.valueType, true, !node.isConst);
    if (node.isConst && ((valueType instanceof ParameterType) || valueType.get$hasTypeParams())) {
      $globals.world.error("type parameter cannot be used in const map literals");
    }
    mapType = mapType.getOrMakeConcreteType([keyType, valueType]);
  }
  for (var i = (0);
   i < node.items.get$length(); i += (2)) {
    var key = this.visitTypedValue(node.items.$index(i), keyType);
    if (node.isConst && !key.get$isConst()) {
      $globals.world.error("const map can only contain const keys", key.get$span());
    }
    values.add(key);
    var value = this.visitTypedValue(node.items.$index(i + (1)), valueType);
    if (node.isConst && !value.get$isConst()) {
      $globals.world.error("const map can only contain const values", value.get$span());
    }
    values.add(value);
  }
  var ret = new MapValue(values, node.isConst, mapType, node.span);
  if (ret.get$isConst()) return ret.getGlobalValue();
  return ret;
}
MethodGenerator.prototype.visitConditionalExpression = function(node) {
  var test = this.visitBool(node.test);
  var trueBranch = this.visitValue(node.trueBranch);
  var falseBranch = this.visitValue(node.falseBranch);
  return new Value(Type.union(trueBranch.get$type(), falseBranch.get$type()), ("" + test.get$code() + " ? " + trueBranch.get$code() + " : " + falseBranch.get$code()), node.span);
}
MethodGenerator.prototype.visitIsExpression = function(node) {
  var value = this.visitValue(node.x);
  var type = this.method.resolveType(node.type, true, true);
  if (type.get$isVar()) {
    return Value.comma(value, Value.fromBool(true, node.span));
  }
  return value.instanceOf$4(this, type, node.span, node.isTrue);
}
MethodGenerator.prototype.visitParenExpression = function(node) {
  var body = this.visitValue(node.body);
  if (body.get$isConst()) return body;
  return new Value(body.get$type(), ("(" + body.get$code() + ")"), node.span);
}
MethodGenerator.prototype.visitDotExpression = function(node) {
  var target = node.self.visit(this);
  return target.get_(this, node.name.name, node.name);
}
MethodGenerator.prototype.visitVarExpression = function(node) {
  var name = node.name.name;
  var ret = this._scope.lookup(name);
  if ($ne$(ret)) return ret;
  return this._makeThisOrType(node.span).get_(this, name, node);
}
MethodGenerator.prototype._makeMissingValue = function(name) {
  return new Value($globals.world.varType, ("" + name + "()/*NotFound*/"), null);
}
MethodGenerator.prototype._makeThisOrType = function(span) {
  return new BareValue(this, this._getOutermostMethod(), span);
}
MethodGenerator.prototype.visitThisExpression = function(node) {
  return this._makeThisValue(node);
}
MethodGenerator.prototype.visitSuperExpression = function(node) {
  return this._makeSuperValue(node);
}
MethodGenerator.prototype.visitLiteralExpression = function(node) {
  return node.value;
}
MethodGenerator.prototype._isUnaryIncrement = function(item) {
  if ((item instanceof UnaryExpression)) {
    var u = item;
    return u.op.kind == (16) || u.op.kind == (17);
  }
  else {
    return false;
  }
}
MethodGenerator.prototype.visitStringInterpExpression = function(node) {
  var items = [];
  var $$list = node.pieces;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var item = $$i.next();
    var val = this.visitValue(item);
    val.invoke(this, "toString", item, Arguments.get$EMPTY());
    var code = val.get$code();
    if (this._expressionNeedsParens(item)) {
      code = ("(" + code + ")");
    }
    if (items.get$length() == (0) || ($ne$(code, "''") && $ne$(code, "\"\""))) {
      items.add(code);
    }
  }
  return new Value($globals.world.stringType, ("(" + Strings.join(items, " + ") + ")"), node.span);
}
MethodGenerator.prototype._pushBlock$1 = function($0) {
  return this._pushBlock($0, false);
};
MethodGenerator.prototype.run$0 = MethodGenerator.prototype.run;
MethodGenerator.prototype.visitBinaryExpression$1 = function($0) {
  return this.visitBinaryExpression($0, false);
};
MethodGenerator.prototype.visitCallExpression$1 = MethodGenerator.prototype.visitCallExpression;
MethodGenerator.prototype.visitPostfixExpression$1 = function($0) {
  return this.visitPostfixExpression($0, false);
};
// ********** Code for Arguments **************
function Arguments(nodes, values) {
  this.nodes = nodes;
  this.values = values;
}
Arguments.Arguments$bare$factory = function(arity) {
  var values = [];
  for (var i = (0);
   i < arity; i++) {
    values.add(new VariableValue($globals.world.varType, ("$" + i), null, false));
  }
  return new Arguments(null, values);
}
Arguments.get$EMPTY = function() {
  if ($globals.Arguments__empty == null) {
    $globals.Arguments__empty = new Arguments(null, []);
  }
  return $globals.Arguments__empty;
}
Arguments.prototype.get$nameCount = function() {
  return this.get$length() - this.get$bareCount();
}
Arguments.prototype.get$hasNames = function() {
  return this.get$bareCount() < this.get$length();
}
Arguments.prototype.get$length = function() {
  return this.values.get$length();
}
Arguments.prototype.getName = function(i) {
  return this.nodes.$index(i).label.name;
}
Arguments.prototype.getIndexOfName = function(name) {
  for (var i = this.get$bareCount();
   i < this.get$length(); i++) {
    if (this.getName(i) == name) {
      return i;
    }
  }
  return (-1);
}
Arguments.prototype.getValue = function(name) {
  var i = this.getIndexOfName(name);
  return i >= (0) ? this.values.$index(i) : null;
}
Arguments.prototype.get$bareCount = function() {
  if (this._bareCount == null) {
    this._bareCount = this.get$length();
    if (this.nodes != null) {
      for (var i = (0);
       i < this.nodes.get$length(); i++) {
        if (this.nodes.$index(i).label != null) {
          this._bareCount = i;
          break;
        }
      }
    }
  }
  return this._bareCount;
}
Arguments.prototype.getCode = function() {
  var argsCode = [];
  for (var i = (0);
   i < this.get$length(); i++) {
    argsCode.add(this.values.$index(i).get$code());
  }
  Arguments.removeTrailingNulls(argsCode);
  return Strings.join(argsCode, ", ");
}
Arguments.removeTrailingNulls = function(argsCode) {
  while (argsCode.get$length() > (0) && $eq$(argsCode.last(), "null")) {
    argsCode.removeLast();
  }
}
Arguments.prototype.getNames = function() {
  var names = [];
  for (var i = this.get$bareCount();
   i < this.get$length(); i++) {
    names.add(this.getName(i));
  }
  return names;
}
Arguments.prototype.toCallStubArgs = function() {
  var result = [];
  for (var i = (0);
   i < this.get$bareCount(); i++) {
    result.add(new VariableValue($globals.world.varType, ("$" + i), null, false));
  }
  for (var i = this.get$bareCount();
   i < this.get$length(); i++) {
    var name = this.getName(i);
    if ($eq$(name)) name = ("$" + i);
    result.add(new VariableValue($globals.world.varType, name, null, false));
  }
  return new Arguments(this.nodes, result);
}
Arguments.prototype.matches = function(other) {
  if (this.get$length() != other.get$length()) return false;
  if (this.get$bareCount() != other.get$bareCount()) return false;
  for (var i = (0);
   i < this.get$bareCount(); i++) {
    if ($ne$(this.values.$index(i).get$type(), other.values.$index(i).get$type())) return false;
  }
  return true;
}
// ********** Code for ReturnKind **************
function ReturnKind() {}
// ********** Code for LibraryImport **************
function LibraryImport(library, prefix, span) {
  this.library = library;
  this.span = span;
  this.prefix = prefix;
}
LibraryImport.prototype.get$prefix = function() { return this.prefix; };
LibraryImport.prototype.get$library = function() { return this.library; };
LibraryImport.prototype.get$span = function() { return this.span; };
// ********** Code for Member **************
$inherits(Member, Element);
function Member(name, declaringType) {
  this._provideGetter = false;
  this._provideSetter = false;
  this.declaringType = declaringType;
  Element.call(this, name, declaringType);
}
Member.prototype.get$declaringType = function() { return this.declaringType; };
Member.prototype.get$genericMember = function() { return this.genericMember; };
Member.prototype.set$genericMember = function(value) { return this.genericMember = value; };
Member.prototype.mangleJsName = function() {
  var mangled = Element.prototype.mangleJsName.call(this);
  if ($eq$(mangled, "split")) {
    return "split_";
  }
  else if (this.declaringType != null && this.declaringType.get$isTop()) {
    return JsNames.getValid(mangled);
  }
  else {
    return (this.get$isNative() && !this.name.contains(":")) ? this.name : mangled;
  }
}
Member.prototype.get$library = function() {
  return this.declaringType.get$library();
}
Member.prototype.get$isPrivate = function() {
  return null != this.name && this.name.startsWith("_");
}
Member.prototype.get$isConstructor = function() {
  return false;
}
Member.prototype.get$isField = function() {
  return false;
}
Member.prototype.get$isMethod = function() {
  return false;
}
Member.prototype.get$isProperty = function() {
  return false;
}
Member.prototype.get$isAbstract = function() {
  return false;
}
Member.prototype.get$isFinal = function() {
  return false;
}
Member.prototype.get$isConst = function() {
  return false;
}
Member.prototype.get$isFactory = function() {
  return false;
}
Member.prototype.get$isOperator = function() {
  return this.name.startsWith(":");
}
Member.prototype.get$isCallMethod = function() {
  return this.name == ":call";
}
Member.prototype.get$isNative = function() {
  return false;
}
Member.prototype.get$constructorName = function() {
  $globals.world.internalError("cannot be a constructor", this.get$span());
}
Member.prototype.provideGetter = function() {

}
Member.prototype.provideSetter = function() {

}
Member.prototype.get$initDelegate = function() {
  $globals.world.internalError("cannot have initializers", this.get$span());
}
Member.prototype.set$initDelegate = function(ctor) {
  $globals.world.internalError("cannot have initializers", this.get$span());
}
Member.prototype.computeValue = function() {
  $globals.world.internalError("cannot have value", this.get$span());
}
Member.prototype.get$inferredResult = function() {
  var t = this.get$returnType();
  if (t.get$isBool() && (this.get$library().get$isCore() || this.get$library().get$isCoreImpl())) {
    return $globals.world.nonNullBool;
  }
  return t;
}
Member.prototype.get$definition = function() {
  return null;
}
Member.prototype.get$parameters = function() {
  return [];
}
Member.prototype.get$preciseMemberSet = function() {
  if (null == this._preciseMemberSet) {
    this._preciseMemberSet = new MemberSet(this, false);
  }
  return this._preciseMemberSet;
}
Member.prototype.get$potentialMemberSet = function() {
  if (null == this._potentialMemberSet) {
    if (this.name == ":call") {
      this._potentialMemberSet = this.get$preciseMemberSet();
      return this._potentialMemberSet;
    }
    var mems = new HashSetImplementation_Member();
    if (this.declaringType.get$isClass()) mems.add(this);
    var $$list = this.declaringType.get$genericType().get$subtypes();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var subtype = $$i.next();
      if (!subtype.get$isClass()) continue;
      var mem = subtype.get$members().$index(this.name);
      if (null != mem) {
        if (mem.isDefinedOn(this.declaringType)) {
          mems.add(mem);
        }
      }
      else if (!this.declaringType.get$isClass()) {
        mem = subtype.getMember(this.name);
        if (null != mem && mem.isDefinedOn(this.declaringType)) {
          mems.add(mem);
        }
      }
    }
    if (mems.get$length() != (0)) {
      for (var $$i = mems.iterator(); $$i.hasNext(); ) {
        var mem = $$i.next();
        if ($ne$(this.declaringType.get$genericType(), this.declaringType) && mem.get$genericMember() != null && mems.contains$1(mem.get$genericMember())) {
          mems.remove$1(mem.get$genericMember());
        }
      }
      for (var $$i = mems.iterator(); $$i.hasNext(); ) {
        var mem = $$i.next();
        if (null == this._potentialMemberSet) {
          this._potentialMemberSet = new MemberSet(mem, false);
        }
        else {
          this._potentialMemberSet.add(mem);
        }
      }
    }
  }
  return this._potentialMemberSet;
}
Member.prototype.isDefinedOn = function(type) {
  if (type.get$isClass()) {
    if (this.declaringType.isSubtypeOf(type)) {
      return true;
    }
    else if (type.isSubtypeOf(this.declaringType)) {
      return $eq$(type.getMember(this.name), this);
    }
    else {
      return false;
    }
  }
  else {
    if (this.declaringType.isSubtypeOf(type)) {
      return true;
    }
    else {
      var $$list = this.declaringType.get$subtypes();
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var t = $$i.next();
        if (t.isSubtypeOf(type) && $eq$(t.getMember(this.name), this)) {
          return true;
        }
      }
      return false;
    }
  }
}
Member.prototype.canInvoke = function(context, args) {
  if (this.get$canGet() && (this.get$isField() || this.get$isProperty())) {
    return this.get$returnType().get$isFunction() || this.get$returnType().get$isVar() || this.get$returnType().getCallMethod() != null;
  }
  return false;
}
Member.prototype.invoke = function(context, node, target, args) {
  var newTarget = this._get(context, node, target);
  return newTarget.invoke(context, ":call", node, args);
}
Member.prototype.override = function(other) {
  if (this.get$isStatic()) {
    $globals.world.error("static members cannot hide parent members", this.get$span(), other.get$span());
    return false;
  }
  else if (other.get$isStatic()) {
    $globals.world.error("cannot override static member", this.get$span(), other.get$span());
    return false;
  }
  return true;
}
Member.prototype.get$generatedFactoryName = function() {
  var prefix = ("" + this.declaringType.get$genericType().get$jsname() + "." + this.get$constructorName() + "$");
  if (this.name == "") {
    return ("" + prefix + "factory");
  }
  else {
    return ("" + prefix + this.name + "$factory");
  }
}
Member.prototype.hashCode = function() {
  var typeCode = this.declaringType == null ? (1) : this.declaringType.hashCode();
  var nameCode = this.get$isConstructor() ? this.get$constructorName().hashCode() : this.name.hashCode();
  return $bit_xor$(($shl$(typeCode, (4))), nameCode);
}
Member.prototype.$eq = function(other) {
  return (other instanceof Member) && $eq$(this.get$isConstructor(), other.get$isConstructor()) && $eq$(this.declaringType, other.get$declaringType()) && (this.get$isConstructor() ? this.get$constructorName() == other.get$constructorName() : this.name == other.get$name());
}
Member.prototype.resolveType = function(node, typeErrors, allowTypeParams) {
  allowTypeParams = allowTypeParams && !(this.get$isStatic() && !this.get$isFactory());
  return Element.prototype.resolveType.call(this, node, typeErrors, allowTypeParams);
}
Member.prototype.makeConcrete = function(concreteType) {
  $globals.world.internalError("cannot make this concrete", this.get$span());
}
// ********** Code for AmbiguousMember **************
$inherits(AmbiguousMember, Member);
function AmbiguousMember(name, members) {
  this.members = members;
  Member.call(this, name, null);
}
AmbiguousMember.prototype.get$members = function() { return this.members; };
// ********** Code for Library **************
$inherits(Library, Element);
function Library(baseSource) {
  this.baseSource = baseSource;
  this.isWritten = false;
  Element.call(this, null, null);
  this.sourceDir = dirname(this.baseSource.filename);
  this.topType = new DefinedType(null, this, null, true);
  this.types = _map(["", this.topType]);
  this.imports = [];
  this.natives = [];
  this.sources = [];
  this._privateMembers = new HashMapImplementation();
}
Library.prototype.get$baseSource = function() { return this.baseSource; };
Library.prototype.get$types = function() { return this.types; };
Library.prototype.get$imports = function() { return this.imports; };
Library.prototype.get$_privateMembers = function() { return this._privateMembers; };
Library.prototype.get$enclosingElement = function() {
  return null;
}
Library.prototype.get$library = function() {
  return this;
}
Library.prototype.get$isNative = function() {
  return this.topType.isNative;
}
Library.prototype.get$isCore = function() {
  return $eq$(this, $globals.world.corelib);
}
Library.prototype.get$isCoreImpl = function() {
  return $eq$(this, $globals.world.coreimpl);
}
Library.prototype.get$isDom = function() {
  return $eq$(this, $globals.world.dom);
}
Library.prototype.get$span = function() {
  return new SourceSpan(this.baseSource, (0), (0));
}
Library.prototype.makeFullPath = function(filename) {
  if (filename.startsWith("dart:")) return filename;
  if (filename.startsWith("/")) return filename;
  if (filename.startsWith("file:///")) return filename;
  if (filename.startsWith("http://")) return filename;
  if (const$0009.hasMatch(filename)) return filename;
  return joinPaths(this.sourceDir, filename);
}
Library.prototype.addImport = function(fullname, prefix, span) {
  var newLib = $globals.world.getOrAddLibrary(fullname);
  if (newLib.get$isCore()) return;
  this.imports.add(new LibraryImport(newLib, prefix, span));
  return newLib;
}
Library.prototype.addNative = function(fullname) {
  this.natives.add($globals.world.reader.readFile(fullname));
}
Library.prototype._findMembers = function(name) {
  if (name.startsWith("_")) {
    return this._privateMembers.$index(name);
  }
  else {
    return $globals.world._members.$index(name);
  }
}
Library.prototype._addMember = function(member) {
  if (member.get$isPrivate()) {
    if (member.get$isStatic()) {
      if (member.declaringType.get$isTop()) {
        $globals.world._addTopName(member);
      }
      return;
    }
    var mset = this._privateMembers.$index(member.name);
    if ($eq$(mset)) {
      var $$list = $globals.world.libraries.getValues();
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var lib = $$i.next();
        if (lib.get$_privateMembers().containsKey(member.get$jsname())) {
          member._jsname = ("_" + this.get$jsname() + member.get$jsname());
          break;
        }
      }
      mset = new MemberSet(member, true);
      this._privateMembers.$setindex(member.name, mset);
    }
    else {
      mset.get$members().add(member);
    }
  }
  else {
    $globals.world._addMember(member);
  }
}
Library.prototype.getOrAddFunctionType = function(enclosingElement, name, func, data) {
  var def = new FunctionTypeDefinition(func, null, func.span);
  var type = new DefinedType(name, this, def, false);
  type.addMethod(":call", func);
  var m = type.get$members().$index(":call");
  m.set$enclosingElement(enclosingElement);
  m.resolve();
  m.set$_methodData(data);
  type.set$interfaces([$globals.world.functionType]);
  return type;
}
Library.prototype.addType = function(name, definition, isClass) {
  if (this.types.containsKey(name)) {
    var existingType = this.types.$index(name);
    if ((this.get$isCore() || this.get$isCoreImpl()) && $eq$(existingType.get$definition())) {
      existingType.setDefinition(definition);
    }
    else {
      $globals.world.warning(("duplicate definition of " + name), definition.span, existingType.get$span());
    }
  }
  else {
    this.types.$setindex(name, new DefinedType(name, this, definition, isClass));
  }
  return this.types.$index(name);
}
Library.prototype.findType = function(type) {
  var result = this.findTypeByName(type.name.name);
  if (result == null) return null;
  if (type.names != null) {
    if (type.names.get$length() > (1)) {
      return null;
    }
    if (!result.get$isTop()) {
      return null;
    }
    return result.get$library().findTypeByName(type.names.$index((0)).name);
  }
  return result;
}
Library.prototype.findTypeByName = function(name) {
  var ret = this.types.$index(name);
  var $$list = this.imports;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var imported = $$i.next();
    var newRet = null;
    if (imported.get$prefix() == null) {
      newRet = imported.get$library().types.$index(name);
    }
    else if (imported.get$prefix() == name) {
      newRet = imported.get$library().topType;
    }
    if ($ne$(newRet)) {
      if ($ne$(ret) && $ne$(ret, newRet)) {
        $globals.world.error(("conflicting types for \"" + name + "\""), ret.get$span(), newRet.get$span());
      }
      else {
        ret = newRet;
      }
    }
  }
  return ret;
}
Library.prototype.resolveType = function(node, typeErrors, allowTypeParams) {
  if (node == null) return $globals.world.varType;
  var ret = this.findType(node);
  if ($eq$(ret)) {
    var message = ("cannot find type " + Library._getDottedName(node));
    if (typeErrors) {
      $globals.world.error(message, node.span);
      return $globals.world.objectType;
    }
    else {
      $globals.world.warning(message, node.span);
      return $globals.world.varType;
    }
  }
  return ret;
}
Library._getDottedName = function(type) {
  if (type.names != null) {
    var names = map(type.names, (function (n) {
      return n.get$name();
    })
    );
    return $add$($add$(type.name.name, "."), Strings.join(names, "."));
  }
  else {
    return type.name.name;
  }
}
Library.prototype.lookup = function(name, span) {
  return this._topNames.$index(name);
}
Library.prototype.resolve = function() {
  if (this.name == null) {
    this.name = this.baseSource.filename;
    var index = this.name.lastIndexOf("/", this.name.length);
    if ($gte$(index, (0))) {
      this.name = this.name.substring($add$(index, (1)));
    }
    index = this.name.indexOf(".");
    if ($gt$(index, (0))) {
      this.name = this.name.substring((0), index);
    }
  }
  this._jsname = this.name.replaceAll(".", "_").replaceAll(":", "_").replaceAll(" ", "_");
  var $$list = this.types.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var type = $$i.next();
    type.resolve();
  }
}
Library.prototype._addTopName = function(name, member, localSpan) {
  var existing = this._topNames.$index(name);
  if (null == existing) {
    this._topNames.$setindex(name, member);
  }
  else {
    if ((existing instanceof AmbiguousMember)) {
      existing.get$members().add(member);
    }
    else {
      var newMember = new AmbiguousMember(name, [existing, member]);
      $globals.world.error(("conflicting members for \"" + name + "\""), existing.get$span(), member.get$span(), localSpan);
      this._topNames.$setindex(name, newMember);
    }
  }
}
Library.prototype._addTopNames = function(lib) {
  var $$list = lib.topType.members.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var member = $$i.next();
    if (member.get$isPrivate() && $ne$(lib, this)) continue;
    this._addTopName(member.get$name(), member);
  }
  var $$list = lib.types.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var type = $$i.next();
    if (!type.get$isTop()) {
      if ($ne$(lib, this) && type.get$typeMember().get$isPrivate()) continue;
      this._addTopName(type.get$name(), type.get$typeMember());
    }
  }
}
Library.prototype.postResolveChecks = function() {
  this._topNames = new HashMapImplementation();
  this._addTopNames(this);
  var $$list = this.imports;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var imported = $$i.next();
    if (imported.get$prefix() == null) {
      this._addTopNames(imported.get$library());
    }
    else {
      this._addTopName(imported.get$prefix(), imported.get$library().topType.get$typeMember(), imported.get$span());
    }
  }
}
Library.prototype.visitSources = function() {
  var visitor = new _LibraryVisitor(this);
  visitor.addSource(this.baseSource);
}
Library.prototype.toString = function() {
  return this.baseSource.filename;
}
Library.prototype.hashCode = function() {
  return this.baseSource.filename.hashCode();
}
Library.prototype.$eq = function(other) {
  return (other instanceof Library) && other.get$baseSource().filename == this.baseSource.filename;
}
Library.prototype.toString$0 = Library.prototype.toString;
// ********** Code for _LibraryVisitor **************
function _LibraryVisitor(library) {
  this.library = library;
  this.isTop = true;
  this.seenSource = false;
  this.seenResource = false;
  this.seenImport = false;
  this.currentType = this.library.topType;
  this.sources = [];
}
_LibraryVisitor.prototype.get$library = function() { return this.library; };
_LibraryVisitor.prototype.get$isTop = function() { return this.isTop; };
_LibraryVisitor.prototype.addSourceFromName = function(name, span) {
  var filename = this.library.makeFullPath(name);
  if ($eq$(filename, this.library.baseSource.filename)) {
    $globals.world.error("library cannot source itself", span);
    return;
  }
  else if (this.sources.some((function (s) {
    return s.get$filename() == filename;
  })
  )) {
    $globals.world.error(("file \"" + filename + "\" has already been sourced"), span);
    return;
  }
  var source = $globals.world.readFile(this.library.makeFullPath(name));
  this.sources.add(source);
}
_LibraryVisitor.prototype.addSource = function(source) {
  var $this = this; // closure support
  if (this.library.sources.some((function (s) {
    return s.get$filename() == source.filename;
  })
  )) {
    $globals.world.error(("duplicate source file \"" + source.filename + "\""));
    return;
  }
  this.library.sources.add(source);
  var parser = new Parser(source, $globals.options.dietParse, false, false, (0));
  var unit = parser.compilationUnit();
  unit.forEach((function (def) {
    return def.visit($this);
  })
  );
  this.isTop = false;
  var newSources = this.sources;
  this.sources = [];
  for (var $$i = newSources.iterator(); $$i.hasNext(); ) {
    var newSource = $$i.next();
    this.addSource(newSource);
  }
}
_LibraryVisitor.prototype.visitDirectiveDefinition = function(node) {
  if (!this.isTop) {
    $globals.world.error("directives not allowed in sourced file", node.span);
    return;
  }
  var name;
  switch (node.name.name) {
    case "library":

      name = this.getSingleStringArg(node);
      if (this.library.name == null) {
        this.library.name = name;
        if ($eq$(name, "node") || $eq$(name, "dom")) {
          this.library.topType.isNative = true;
        }
        if (this.seenImport || this.seenSource || this.seenResource) {
          $globals.world.error("#library must be first directive in file", node.span);
        }
      }
      else {
        $globals.world.error("already specified library name", node.span);
      }
      break;

    case "import":

      this.seenImport = true;
      name = this.getFirstStringArg(node);
      var prefix = this.tryGetNamedStringArg(node, "prefix");
      if (node.arguments.get$length() > (2) || node.arguments.get$length() == (2) && $eq$(prefix)) {
        $globals.world.error($add$("expected at most one \"name\" argument and one optional \"prefix\"", (" but found " + node.arguments.get$length())), node.span);
      }
      else if ($ne$(prefix) && $gte$(prefix.indexOf$1("."), (0))) {
        $globals.world.error("library prefix canot contain \".\"", node.span);
      }
      else if (this.seenSource || this.seenResource) {
        $globals.world.error("#imports must come before any #source or #resource", node.span);
      }
      if ($eq$(prefix, "")) prefix = null;
      var filename = this.library.makeFullPath(name);
      if (this.library.imports.some((function (li) {
        return $eq$(li.get$library().baseSource, filename);
      })
      )) {
        $globals.world.error(("duplicate import of \"" + name + "\""), node.span);
        return;
      }
      var newLib = this.library.addImport(filename, prefix, node.span);
      break;

    case "source":

      this.seenSource = true;
      name = this.getSingleStringArg(node);
      this.addSourceFromName(name, node.span);
      if (this.seenResource) {
        $globals.world.error("#sources must come before any #resource", node.span);
      }
      break;

    case "native":

      name = this.getSingleStringArg(node);
      this.library.addNative(this.library.makeFullPath(name));
      break;

    case "resource":

      this.seenResource = true;
      this.getFirstStringArg(node);
      break;

    default:

      $globals.world.error(("unknown directive: " + node.name.name), node.span);

  }
}
_LibraryVisitor.prototype.getSingleStringArg = function(node) {
  if (node.arguments.get$length() != (1)) {
    $globals.world.error(("expected exactly one argument but found " + node.arguments.get$length()), node.span);
  }
  return this.getFirstStringArg(node);
}
_LibraryVisitor.prototype.getFirstStringArg = function(node) {
  if (node.arguments.get$length() < (1)) {
    $globals.world.error(("expected at least one argument but found " + node.arguments.get$length()), node.span);
  }
  var arg = node.arguments.$index((0));
  if (arg.get$label() != null) {
    $globals.world.error("label not allowed for directive", node.span);
  }
  return this._parseStringArgument(arg);
}
_LibraryVisitor.prototype.tryGetNamedStringArg = function(node, argName) {
  var args = node.arguments.filter((function (a) {
    return a.get$label() != null && a.get$label().name == argName;
  })
  );
  if (args.get$length() == (0)) {
    return null;
  }
  if (args.get$length() > (1)) {
    $globals.world.error(("expected at most one \"" + argName + "\" argument but found ") + node.arguments.get$length(), node.span);
  }
  for (var $$i = args.iterator(); $$i.hasNext(); ) {
    var arg = $$i.next();
    return this._parseStringArgument(arg);
  }
}
_LibraryVisitor.prototype._parseStringArgument = function(arg) {
  var expr = arg.value;
  if (!(expr instanceof LiteralExpression) || !expr.get$value().get$type().get$isString()) {
    $globals.world.error("expected string literal", expr.get$span());
  }
  return expr.get$value().get$actualValue();
}
_LibraryVisitor.prototype.visitTypeDefinition = function(node) {
  var oldType = this.currentType;
  this.currentType = this.library.addType(node.name.name, node, node.isClass);
  var $$list = node.body;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var member = $$i.next();
    member.visit(this);
  }
  this.currentType = oldType;
}
_LibraryVisitor.prototype.visitVariableDefinition = function(node) {
  this.currentType.addField(node);
}
_LibraryVisitor.prototype.visitFunctionDefinition = function(node) {
  this.currentType.addMethod(node.name.name, node);
}
_LibraryVisitor.prototype.visitFunctionTypeDefinition = function(node) {
  var type = this.library.addType(node.func.name.name, node, false);
  type.addMethod(":call", node.func);
}
// ********** Code for Parameter **************
function Parameter(definition, method) {
  this.method = method;
  this.definition = definition;
  this.isInitializer = false;
}
Parameter.prototype.get$definition = function() { return this.definition; };
Parameter.prototype.get$method = function() { return this.method; };
Parameter.prototype.get$name = function() { return this.name; };
Parameter.prototype.set$name = function(value) { return this.name = value; };
Parameter.prototype.get$type = function() { return this.type; };
Parameter.prototype.get$isInitializer = function() { return this.isInitializer; };
Parameter.prototype.get$value = function() { return this.value; };
Parameter.prototype.set$value = function(value) { return this.value = value; };
Parameter.prototype.resolve = function() {
  this.name = this.definition.name.name;
  if (this.name.startsWith("this.")) {
    this.name = this.name.substring((5));
    this.isInitializer = true;
  }
  this.type = this.method.resolveType(this.definition.type, false, true);
  if (this.definition.value != null) {
    if (!this.get$hasDefaultValue()) return;
    if (this.method.name == ":call") {
      var methodDef = this.method.get$definition();
      if ($eq$(methodDef.get$body()) && !this.method.get$isNative()) {
        $globals.world.error("default value not allowed on function type", this.definition.span);
      }
    }
    else if (this.method.get$isAbstract()) {
      $globals.world.error("default value not allowed on abstract methods", this.definition.span);
    }
  }
  else if (this.isInitializer && !this.method.get$isConstructor()) {
    $globals.world.error("initializer parameters only allowed on constructors", this.definition.span);
  }
}
Parameter.prototype.genValue = function(method, context) {
  if (this.definition.value == null || this.value != null) return;
  if ((context instanceof MethodGenerator)) {
    var gen = context;
    this.value = this.definition.value.visit(gen);
    if (!this.value.get$isConst()) {
      $globals.world.error("default parameter values must be constant", this.value.span);
    }
    this.value = this.value.convertTo(context, this.type);
  }
}
Parameter.prototype.get$isOptional = function() {
  return this.definition != null && this.definition.value != null;
}
Parameter.prototype.get$hasDefaultValue = function() {
  return this.definition.value.span.start != this.definition.span.start;
}
// ********** Code for TypeMember **************
$inherits(TypeMember, Member);
function TypeMember(type) {
  this.type = type;
  Member.call(this, type.name, type.library.topType);
}
TypeMember.prototype.get$type = function() { return this.type; };
TypeMember.prototype.get$span = function() {
  return null == this.type.definition ? null : this.type.definition.span;
}
TypeMember.prototype.get$isStatic = function() {
  return true;
}
TypeMember.prototype.get$returnType = function() {
  return $globals.world.varType;
}
TypeMember.prototype.canInvoke = function(context, args) {
  return false;
}
TypeMember.prototype.get$canGet = function() {
  return true;
}
TypeMember.prototype.get$canSet = function() {
  return false;
}
TypeMember.prototype._get = function(context, node, target) {
  return new TypeValue(this.type, node.span);
}
TypeMember.prototype._set = function(context, node, target, value) {
  $globals.world.error("cannot set type", node.span);
}
TypeMember.prototype.invoke = function(context, node, target, args) {
  $globals.world.error("cannot invoke type", node.span);
}
// ********** Code for FieldMember **************
$inherits(FieldMember, Member);
function FieldMember(name, declaringType, definition, value, isNative) {
  this.isNative = isNative;
  this.definition = definition;
  this._computing = false;
  this.value = value;
  Member.call(this, name, declaringType);
}
FieldMember.prototype.get$definition = function() { return this.definition; };
FieldMember.prototype.get$value = function() { return this.value; };
FieldMember.prototype.get$type = function() { return this.type; };
FieldMember.prototype.get$isStatic = function() { return this.isStatic; };
FieldMember.prototype.set$isStatic = function(value) { return this.isStatic = value; };
FieldMember.prototype.get$isFinal = function() { return this.isFinal; };
FieldMember.prototype.get$isNative = function() { return this.isNative; };
FieldMember.prototype.override = function(other) {
  if (!Member.prototype.override.call(this, other)) return false;
  if (other.get$isProperty() || other.get$isField()) {
    return true;
  }
  else {
    $globals.world.error("field can only override field or property", this.get$span(), other.get$span());
    return false;
  }
}
FieldMember.prototype.provideGetter = function() {
  this._provideGetter = true;
  if (null != this.genericMember) {
    this.genericMember.provideGetter();
  }
}
FieldMember.prototype.provideSetter = function() {
  this._provideSetter = true;
  if (null != this.genericMember) {
    this.genericMember.provideSetter();
  }
}
FieldMember.prototype.makeConcrete = function(concreteType) {
  var ret = new FieldMember(this.name, concreteType, this.definition, this.value, false);
  ret.set$genericMember(this);
  ret.set$_jsname(this._jsname);
  return ret;
}
FieldMember.prototype.get$span = function() {
  return this.definition == null ? null : this.definition.span;
}
FieldMember.prototype.get$returnType = function() {
  return this.type;
}
FieldMember.prototype.get$canGet = function() {
  return true;
}
FieldMember.prototype.get$canSet = function() {
  return !this.isFinal;
}
FieldMember.prototype.get$isField = function() {
  return true;
}
FieldMember.prototype.resolve = function() {
  this.isStatic = this.declaringType.get$isTop();
  this.isFinal = false;
  if (this.definition.modifiers != null) {
    var $$list = this.definition.modifiers;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var mod = $$i.next();
      if (mod.get$kind() == (85)) {
        if (this.isStatic) {
          $globals.world.error("duplicate static modifier", mod.get$span());
        }
        this.isStatic = true;
      }
      else if (mod.get$kind() == (99)) {
        if (this.isFinal) {
          $globals.world.error("duplicate final modifier", mod.get$span());
        }
        this.isFinal = true;
      }
      else {
        $globals.world.error(("" + mod + " modifier not allowed on field"), mod.get$span());
      }
    }
  }
  this.type = this.resolveType(this.definition.type, false, true);
  if (this.isStatic && this.isFinal && this.value == null) {
    $globals.world.error("static final field is missing initializer", this.get$span());
  }
  if (this.declaringType.get$isClass()) this.get$library()._addMember(this);
}
FieldMember.prototype.computeValue = function() {
  if (this.value == null) return null;
  if (this._computedValue == null) {
    if (this._computing) {
      $globals.world.error("circular reference", this.value.span);
      return null;
    }
    this._computing = true;
    var finalMethod = new MethodMember("final_context", this.declaringType, null);
    finalMethod.set$isStatic(true);
    var finalGen = new MethodGenerator(finalMethod, null);
    this._computedValue = this.value.visit(finalGen);
    if (!this._computedValue.get$isConst()) {
      if (this.isStatic) {
        $globals.world.error("non constant static field must be initialized in functions", this.value.span);
      }
      else {
        $globals.world.error("non constant field must be initialized in constructor", this.value.span);
      }
    }
    if (this.isStatic) {
      if (this.isFinal && this._computedValue.get$isConst()) {
        ;
      }
      else {
        this._computedValue = $globals.world.gen.globalForStaticField(this, this._computedValue, [this._computedValue]);
      }
    }
    this._computing = false;
  }
  return this._computedValue;
}
FieldMember.prototype._get = function(context, node, target) {
  if (!context.get$needsCode()) {
    return new PureStaticValue(this.type, node.span, this.isStatic && this.isFinal, false);
  }
  if (this.isNative && this.get$returnType() != null) {
    this.get$returnType().markUsed();
    if ((this.get$returnType() instanceof DefinedType)) {
      var defaultType = this.get$returnType().get$genericType().defaultType;
      if ($ne$(defaultType) && defaultType.get$isNative()) {
        defaultType.markUsed();
      }
    }
  }
  if (this.isStatic) {
    this.declaringType.markUsed();
    var cv = this.computeValue();
    if (this.isFinal) {
      return cv;
    }
    $globals.world.gen.hasStatics = true;
    if (this.declaringType.get$isTop()) {
      if (this.declaringType.get$library().get$isDom()) {
        return new Value(this.type, ("" + this.get$jsname()), node.span);
      }
      else {
        return new Value(this.type, ("$globals." + this.get$jsname()), node.span);
      }
    }
    else if (this.declaringType.get$isNative()) {
      if (this.declaringType.get$isHiddenNativeType()) {
        $globals.world.error("static field of hidden native type is inaccessible", node.span);
      }
      return new Value(this.type, ("" + this.declaringType.get$jsname() + "." + this.get$jsname()), node.span);
    }
    else {
      return new Value(this.type, ("$globals." + this.declaringType.get$jsname() + "_" + this.get$jsname()), node.span);
    }
  }
  return new Value(this.type, ("" + target.get$code() + "." + this.get$jsname()), node.span);
}
FieldMember.prototype._set = function(context, node, target, value) {
  if (!context.get$needsCode()) {
    return new PureStaticValue(this.type, node.span, false, false);
  }
  var lhs = this._get(context, node, target);
  value = value.convertTo(context, this.type);
  return new Value(this.type, ("" + lhs.get$code() + " = " + value.get$code()), node.span);
}
// ********** Code for PropertyMember **************
$inherits(PropertyMember, Member);
function PropertyMember(name, declaringType) {
  Member.call(this, name, declaringType);
}
PropertyMember.prototype.get$getter = function() { return this.getter; };
PropertyMember.prototype.set$getter = function(value) { return this.getter = value; };
PropertyMember.prototype.get$setter = function() { return this.setter; };
PropertyMember.prototype.set$setter = function(value) { return this.setter = value; };
PropertyMember.prototype.get$span = function() {
  return this.getter != null ? this.getter.get$span() : null;
}
PropertyMember.prototype.get$canGet = function() {
  return this.getter != null;
}
PropertyMember.prototype.get$canSet = function() {
  return this.setter != null;
}
PropertyMember.prototype.get$needsFieldSyntax = function() {
  return this._overriddenField != null && this._overriddenField.get$isNative() && !this._overriddenField.declaringType.get$isHiddenNativeType();
}
PropertyMember.prototype.get$isStatic = function() {
  return this.getter == null ? this.setter.isStatic : this.getter.isStatic;
}
PropertyMember.prototype.get$isProperty = function() {
  return true;
}
PropertyMember.prototype.get$returnType = function() {
  return this.getter == null ? this.setter.returnType : this.getter.returnType;
}
PropertyMember.prototype.makeConcrete = function(concreteType) {
  var ret = new PropertyMember(this.name, concreteType);
  if (null != this.getter) ret.set$getter(this.getter.makeConcrete(concreteType));
  if (null != this.setter) ret.set$setter(this.setter.makeConcrete(concreteType));
  ret.set$_jsname(this._jsname);
  return ret;
}
PropertyMember.prototype.override = function(other) {
  if (!Member.prototype.override.call(this, other)) return false;
  if (other.get$isProperty() || other.get$isField()) {
    if (other.get$isProperty()) this.addFromParent(other);
    else this._overriddenField = other;
    return true;
  }
  else {
    $globals.world.error("property can only override field or property", this.get$span(), other.get$span());
    return false;
  }
}
PropertyMember.prototype._get = function(context, node, target) {
  if (this.getter == null) {
    if (this._overriddenField != null) {
      return this._overriddenField._get(context, node, target);
    }
    return target.invokeNoSuchMethod$3(context, ("get:" + this.name), node);
  }
  return this.getter.invoke(context, node, target, Arguments.get$EMPTY());
}
PropertyMember.prototype._set = function(context, node, target, value) {
  if (this.setter == null) {
    if (this._overriddenField != null) {
      return this._overriddenField._set(context, node, target, value);
    }
    return target.invokeNoSuchMethod(context, ("set:" + this.name), node, new Arguments(null, [value]));
  }
  return this.setter.invoke(context, node, target, new Arguments(null, [value]));
}
PropertyMember.prototype.addFromParent = function(parentMember) {
  var parent = parentMember;
  if (this.getter == null) this.getter = parent.get$getter();
  if (this.setter == null) this.setter = parent.get$setter();
}
PropertyMember.prototype.resolve = function() {
  if (this.getter != null) {
    this.getter.resolve();
    if (this.getter.parameters.get$length() != (0)) {
      $globals.world.error("getter methods should take no arguments", this.getter.definition.span);
    }
    if (this.getter.returnType.get$isVoid()) {
      $globals.world.warning("getter methods should not be void", this.getter.definition.returnType.span);
    }
  }
  if (this.setter != null) {
    this.setter.resolve();
    if (this.setter.parameters.get$length() != (1)) {
      $globals.world.error("setter methods should take a single argument", this.setter.definition.span);
    }
    if (!this.setter.returnType.get$isVoid() && this.setter.definition.returnType != null) {
      $globals.world.warning("setter methods should be void", this.setter.definition.returnType.span);
    }
  }
  if (this.declaringType.get$isClass()) this.get$library()._addMember(this);
}
// ********** Code for MethodMember **************
$inherits(MethodMember, Member);
function MethodMember(name, declaringType, definition) {
  this.isLambda = false;
  this._provideOptionalParamInfo = false;
  this.isFactory = false;
  this.definition = definition;
  this.isConst = false;
  this.isAbstract = false;
  this.isStatic = false;
  Member.call(this, name, declaringType);
}
MethodMember.lambda$ctor = function(name, declaringType, definition) {
  this.isLambda = true;
  this._provideOptionalParamInfo = false;
  this.isFactory = false;
  this.definition = definition;
  this.isConst = false;
  this.isAbstract = false;
  this.isStatic = false;
  Member.call(this, name, declaringType);
}
MethodMember.lambda$ctor.prototype = MethodMember.prototype;
MethodMember.prototype.get$definition = function() { return this.definition; };
MethodMember.prototype.get$returnType = function() { return this.returnType; };
MethodMember.prototype.set$returnType = function(value) { return this.returnType = value; };
MethodMember.prototype.get$parameters = function() { return this.parameters; };
MethodMember.prototype.set$parameters = function(value) { return this.parameters = value; };
MethodMember.prototype.set$_methodData = function(value) { return this._methodData = value; };
MethodMember.prototype.get$isStatic = function() { return this.isStatic; };
MethodMember.prototype.set$isStatic = function(value) { return this.isStatic = value; };
MethodMember.prototype.get$isAbstract = function() { return this.isAbstract; };
MethodMember.prototype.set$isAbstract = function(value) { return this.isAbstract = value; };
MethodMember.prototype.get$isConst = function() { return this.isConst; };
MethodMember.prototype.get$isFactory = function() { return this.isFactory; };
MethodMember.prototype.get$initDelegate = function() { return this.initDelegate; };
MethodMember.prototype.set$initDelegate = function(value) { return this.initDelegate = value; };
MethodMember.prototype.makeConcrete = function(concreteType) {
  var _name = this.get$isConstructor() ? concreteType.name : this.name;
  var ret = new MethodMember(_name, concreteType, this.definition);
  ret.set$genericMember(this);
  ret.set$_jsname(this._jsname);
  return ret;
}
MethodMember.prototype.get$methodData = function() {
  if (null != this.genericMember) return this.genericMember.get$dynamic().get$methodData();
  if (null == this._methodData) {
    this._methodData = new MethodData(this);
  }
  return this._methodData;
}
MethodMember.prototype.get$isConstructor = function() {
  return this.name == this.declaringType.name;
}
MethodMember.prototype.get$isMethod = function() {
  return !this.get$isConstructor();
}
MethodMember.prototype.get$isNative = function() {
  if (this.definition == null) return false;
  return this.definition.nativeBody != null;
}
MethodMember.prototype.get$canGet = function() {
  return true;
}
MethodMember.prototype.get$canSet = function() {
  return false;
}
MethodMember.prototype.get$span = function() {
  return this.definition == null ? null : this.definition.span;
}
MethodMember.prototype.get$constructorName = function() {
  var returnType = this.definition.returnType;
  if ($eq$(returnType)) return "";
  if ((returnType instanceof GenericTypeReference)) {
    return "";
  }
  if (returnType.get$names() != null) {
    return returnType.get$names().$index((0)).name;
  }
  else if ($ne$(returnType.get$name())) {
    return returnType.get$name().get$name();
  }
  $globals.world.internalError("no valid constructor name", this.definition.span);
}
MethodMember.prototype.get$functionType = function() {
  if (this._functionType == null) {
    this._functionType = this.get$library().getOrAddFunctionType(this.declaringType, this.name, this.definition, this.get$methodData());
    if (this.parameters == null) {
      this.resolve();
    }
  }
  return this._functionType;
}
MethodMember.prototype.override = function(other) {
  if (!Member.prototype.override.call(this, other)) return false;
  if (other.get$isMethod()) {
    return true;
  }
  else {
    $globals.world.error("method can only override methods", this.get$span(), other.get$span());
    return false;
  }
}
MethodMember.prototype.canInvoke = function(context, args) {
  var bareCount = args.get$bareCount();
  if (bareCount > this.parameters.get$length()) return false;
  if (bareCount == this.parameters.get$length()) {
    if (bareCount != args.get$length()) return false;
  }
  else {
    if (!this.parameters.$index(bareCount).get$isOptional()) return false;
    for (var i = bareCount;
     i < args.get$length(); i++) {
      if (this.indexOfParameter(args.getName(i)) < (0)) {
        return false;
      }
    }
  }
  return true;
}
MethodMember.prototype.indexOfParameter = function(name) {
  for (var i = (0);
   i < this.parameters.get$length(); i++) {
    var p = this.parameters.$index(i);
    if (p.get$isOptional() && $eq$(p.get$name(), name)) {
      return i;
    }
  }
  return (-1);
}
MethodMember.prototype.provideGetter = function() {
  this._provideGetter = true;
}
MethodMember.prototype.provideSetter = function() {
  this._provideSetter = true;
}
MethodMember.prototype._set = function(context, node, target, value) {
  $globals.world.error("cannot set method", node.span);
}
MethodMember.prototype._get = function(context, node, target) {
  if (!context.get$needsCode()) {
    return new PureStaticValue(this.get$functionType(), node.span, false, false);
  }
  this.declaringType.genMethod(this);
  this._provideOptionalParamInfo = true;
  if (this.isStatic) {
    this.declaringType.markUsed();
    var type = this.declaringType.get$isTop() ? "" : ("" + this.declaringType.get$jsname() + ".");
    return new Value(this.get$functionType(), ("" + type + this.get$jsname()), node.span);
  }
  this._provideGetter = true;
  return new Value(this.get$functionType(), ("" + target.get$code() + ".get$" + this.get$jsname() + "()"), node.span);
}
MethodMember.prototype.namesInHomePositions = function(args) {
  if (!args.get$hasNames()) return true;
  for (var i = args.get$bareCount();
   i < args.values.get$length(); i++) {
    if (i >= this.parameters.get$length()) {
      return false;
    }
    if (args.getName(i) != this.parameters.$index(i).name) {
      return false;
    }
  }
  return true;
}
MethodMember.prototype.namesInOrder = function(args) {
  if (!args.get$hasNames()) return true;
  var lastParameter = null;
  for (var i = args.get$bareCount();
   i < this.parameters.get$length(); i++) {
    var p = args.getIndexOfName(this.parameters.$index(i).name);
    if ($gte$(p, (0)) && args.values.$index(p).get$needsTemp()) {
      if (lastParameter != null && $gt$(lastParameter, p)) {
        return false;
      }
      lastParameter = p;
    }
  }
  return true;
}
MethodMember.prototype.needsArgumentConversion = function(args) {
  var bareCount = args.get$bareCount();
  for (var i = (0);
   i < bareCount; i++) {
    var arg = args.values.$index(i);
    if (arg.needsConversion(this.parameters.$index(i).type)) {
      return true;
    }
  }
  if (bareCount < this.parameters.get$length()) {
    for (var i = bareCount;
     i < this.parameters.get$length(); i++) {
      var arg = args.getValue(this.parameters.$index(i).name);
      if ($ne$(arg) && arg.needsConversion(this.parameters.$index(i).type)) {
        return true;
      }
    }
  }
  return false;
}
MethodMember.prototype.hasOptionalParameters = function() {
  return this.parameters.some((function (p) {
    return p.get$isOptional();
  })
  );
}
MethodMember.prototype._tooManyArgumentsMsg = function(actual, expected) {
  return this.hasOptionalParameters() ? ("too many arguments, expected at most " + expected + " but found " + actual) : this._wrongArgumentCountMsg(actual, expected);
}
MethodMember.prototype._tooFewArgumentsMsg = function(actual, expected) {
  return this.hasOptionalParameters() ? ("too few arguments, expected at least " + expected + " but found " + actual) : this._wrongArgumentCountMsg(actual, expected);
}
MethodMember.prototype._wrongArgumentCountMsg = function(actual, expected) {
  return ("wrong number of arguments, expected " + expected + " but found " + actual);
}
MethodMember.prototype._argError = function(context, node, target, args, msg, argIndex) {
  if (context.get$showWarnings()) {
    var span;
    if ((args.nodes == null) || (argIndex >= args.nodes.get$length())) {
      span = node.span;
    }
    else {
      span = args.nodes.$index(argIndex).span;
    }
    if (this.isStatic || this.get$isConstructor()) {
      $globals.world.error(msg, span);
    }
    else {
      $globals.world.warning(msg, span);
    }
  }
  return target.invokeNoSuchMethod(context, this.name, node, args);
}
MethodMember.prototype.genParameterValues = function(context) {
  if (context.get$needsCode()) {
    var $$list = this.parameters;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var p = $$i.next();
      p.genValue(this, context);
    }
  }
}
MethodMember.prototype.invoke = function(context, node, target, args) {
  var argValues = [];
  var bareCount = args.get$bareCount();
  for (var i = (0);
   i < bareCount; i++) {
    var arg = args.values.$index(i);
    if (i >= this.parameters.get$length()) {
      var msg = this._tooManyArgumentsMsg(args.get$length(), this.parameters.get$length());
      return this._argError(context, node, target, args, msg, i);
    }
    argValues.add(arg.convertTo(context, this.parameters.$index(i).type));
  }
  var namedArgsUsed = (0);
  if (bareCount < this.parameters.get$length()) {
    this.genParameterValues(context);
    for (var i = bareCount;
     i < this.parameters.get$length(); i++) {
      var param = this.parameters.$index(i);
      var arg = args.getValue(param.get$name());
      if ($eq$(arg)) {
        arg = param.get$value();
        if ($eq$(arg)) {
          arg = new PureStaticValue(param.get$type(), param.get$definition().get$span(), true, false);
        }
      }
      else {
        arg = arg.convertTo(context, this.parameters.$index(i).type);
        namedArgsUsed++;
      }
      if ($eq$(arg) || !this.parameters.$index(i).get$isOptional()) {
        var msg = this._tooFewArgumentsMsg(Math.min(i, args.get$length()), i + (1));
        return this._argError(context, node, target, args, msg, i);
      }
      else {
        argValues.add(arg);
      }
    }
  }
  if (namedArgsUsed < args.get$nameCount()) {
    var seen = new HashSetImplementation_dart_core_String();
    for (var i = bareCount;
     i < args.get$length(); i++) {
      var name = args.getName(i);
      if (seen.contains$1(name)) {
        return this._argError(context, node, target, args, ("duplicate argument \"" + name + "\""), i);
      }
      seen.add(name);
      var p = this.indexOfParameter(name);
      if (p < (0)) {
        return this._argError(context, node, target, args, ("method does not have optional parameter \"" + name + "\""), i);
      }
      else if (p < bareCount) {
        return this._argError(context, node, target, args, ("argument \"" + name + "\" passed as positional and named"), p);
      }
    }
    $globals.world.internalError(("wrong named arguments calling " + this.name), node.span);
  }
  if (!context.get$needsCode()) {
    return new PureStaticValue(this.returnType, node.span, false, false);
  }
  this.declaringType.genMethod(this);
  if (this.isStatic || this.isFactory) {
    this.declaringType.markUsed();
  }
  if (this.get$isNative() && this.returnType != null) this.returnType.markUsed();
  if (!this.namesInOrder(args)) {
    return context.findMembers(this.name).invokeOnVar(context, node, target, args);
  }
  var argsCode = argValues.map((function (v) {
    return v.get$code();
  })
  );
  if (!target.get$isType() && (this.get$isConstructor() || target.get$isSuper())) {
    argsCode.insertRange((0), (1), "this");
  }
  if (bareCount < this.parameters.get$length()) {
    Arguments.removeTrailingNulls(argsCode);
  }
  var argsString = Strings.join(argsCode, ", ");
  if (this.get$isConstructor()) {
    return this._invokeConstructor(context, node, target, args, argsString);
  }
  if (target.get$isSuper()) {
    return new Value(this.get$inferredResult(), ("" + this.declaringType.get$jsname() + ".prototype." + this.get$jsname() + ".call(" + argsString + ")"), node.span);
  }
  if (this.get$isOperator()) {
    return this._invokeBuiltin(context, node, target, args, argsCode);
  }
  if (this.isFactory) {
    return new Value(target.get$type(), ("" + this.get$generatedFactoryName() + "(" + argsString + ")"), null != node ? node.span : null);
  }
  if (this.isStatic) {
    if (this.declaringType.get$isTop()) {
      return new Value(this.get$inferredResult(), ("" + this.get$jsname() + "(" + argsString + ")"), null != node ? node.span : null);
    }
    return new Value(this.get$inferredResult(), ("" + this.declaringType.get$jsname() + "." + this.get$jsname() + "(" + argsString + ")"), node.span);
  }
  if (this.name == "get:typeName" && this.declaringType.get$library().get$isDom()) {
    $globals.world.gen.corejs.ensureTypeNameOf();
  }
  var code = ("" + target.get$code() + "." + this.get$jsname() + "(" + argsString + ")");
  return new Value(this.get$inferredResult(), code, node.span);
}
MethodMember.prototype._invokeConstructor = function(context, node, target, args, argsString) {
  this.declaringType.markUsed();
  var ctor = this.get$constructorName();
  if (ctor != "") ctor = ("." + ctor + "$ctor");
  var span = node != null ? node.span : target.span;
  if (!target.get$isType()) {
    var code = ("" + this.declaringType.get$nativeName() + ctor + ".call(" + argsString + ")");
    return new Value(target.get$type(), code, span);
  }
  else {
    if (this.isConst && (node instanceof NewExpression) && node.get$dynamic().get$isConst()) {
      if (this.get$isNative() || this.declaringType.name == "JSSyntaxRegExp") {
        var code = ("new " + this.declaringType.get$nativeName() + ctor + "(" + argsString + ")");
        return $globals.world.gen.globalForConst(new Value(target.get$type(), code, span), [args.values]);
      }
      var newType = this.declaringType;
      var newObject = new ObjectValue(true, newType, span);
      newObject.initFields();
      this._evalConstConstructor(newObject, args);
      return $globals.world.gen.globalForConst(newObject, [args.values]);
    }
    else {
      var code = ("new " + this.declaringType.get$nativeName() + ctor + "(" + argsString + ")");
      return new Value(target.get$type(), code, span);
    }
  }
}
MethodMember.prototype._evalConstConstructor = function(newObject, args) {
  this.declaringType.markUsed();
  this.get$methodData().eval(this, newObject, args);
}
MethodMember.prototype._invokeBuiltin = function(context, node, target, args, argsCode) {
  if (target.get$type().get$isNum()) {
    var code = null;
    if (args.get$length() == (0)) {
      if (this.name == ":negate") {
        code = ("-" + target.get$code());
      }
      else if (this.name == ":bit_not") {
        code = ("~" + target.get$code());
      }
    }
    else if (args.get$length() == (1) && args.values.$index((0)).get$type().get$isNum()) {
      if (this.name == ":truncdiv" || this.name == ":mod") {
        $globals.world.gen.corejs.useOperator(this.name);
        code = ("" + this.get$jsname() + "$(" + target.get$code() + ", " + argsCode.$index((0)) + ")");
      }
      else {
        var op = TokenKind.rawOperatorFromMethod(this.name);
        code = ("" + target.get$code() + " " + op + " " + argsCode.$index((0)));
      }
    }
    if (null != code) {
      return new Value(this.get$inferredResult(), code, node.span);
    }
  }
  else if (target.get$type().get$isString()) {
    if (this.name == ":index" && args.values.$index((0)).get$type().get$isNum()) {
      return new Value(this.declaringType, ("" + target.get$code() + "[" + argsCode.$index((0)) + "]"), node.span);
    }
    else if (this.name == ":add" && args.values.$index((0)).get$type().get$isNum()) {
      return new Value(this.declaringType, ("" + target.get$code() + " + " + argsCode.$index((0))), node.span);
    }
  }
  else if (this.declaringType.get$isNative() && $globals.options.disableBoundsChecks) {
    if (args.get$length() > (0) && args.values.$index((0)).get$type().get$isNum()) {
      if (this.name == ":index") {
        return new Value(this.returnType, ("" + target.get$code() + "[" + argsCode.$index((0)) + "]"), node.span);
      }
      else if (this.name == ":setindex") {
        return new Value(this.returnType, ("" + target.get$code() + "[" + argsCode.$index((0)) + "] = " + argsCode.$index((1))), node.span);
      }
    }
  }
  if (this.name == ":eq" || this.name == ":ne") {
    var op = this.name == ":eq" ? "==" : "!=";
    if (this.name == ":ne") {
      target.invoke(context, ":eq", node, args);
    }
    if ($eq$(argsCode.$index((0)), "null")) {
      return new Value(this.get$inferredResult(), ("" + target.get$code() + " " + op + " null"), node.span);
    }
    else if (target.get$type().get$isNum() || target.get$type().get$isString()) {
      return new Value(this.get$inferredResult(), ("" + target.get$code() + " " + op + " " + argsCode.$index((0))), node.span);
    }
    $globals.world.gen.corejs.useOperator(this.name);
    return new Value(this.get$inferredResult(), ("" + this.get$jsname() + "$(" + target.get$code() + ", " + argsCode.$index((0)) + ")"), node.span);
  }
  if (this.get$isCallMethod()) {
    this.declaringType.markUsed();
    return new Value(this.get$inferredResult(), ("" + target.get$code() + "(" + Strings.join(argsCode, ", ") + ")"), node.span);
  }
  if (this.name == ":index") {
    $globals.world.gen.corejs.useIndex = true;
  }
  else if (this.name == ":setindex") {
    $globals.world.gen.corejs.useSetIndex = true;
  }
  else {
    $globals.world.gen.corejs.useOperator(this.name);
    var argsString = argsCode.get$length() == (0) ? "" : (", " + argsCode.$index((0)));
    return new Value(this.returnType, ("" + this.get$jsname() + "$(" + target.get$code() + argsString + ")"), node.span);
  }
  var argsString = Strings.join(argsCode, ", ");
  return new Value(this.get$inferredResult(), ("" + target.get$code() + "." + this.get$jsname() + "(" + argsString + ")"), node.span);
}
MethodMember.prototype.resolve = function() {
  this.isStatic = this.declaringType.get$isTop();
  this.isConst = false;
  this.isFactory = false;
  this.isAbstract = !this.declaringType.get$isClass();
  if (this.definition.modifiers != null) {
    var $$list = this.definition.modifiers;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var mod = $$i.next();
      if (mod.get$kind() == (85)) {
        if (this.isStatic) {
          $globals.world.error("duplicate static modifier", mod.get$span());
        }
        this.isStatic = true;
      }
      else if (this.get$isConstructor() && mod.get$kind() == (92)) {
        if (this.isConst) {
          $globals.world.error("duplicate const modifier", mod.get$span());
        }
        if (this.isFactory) {
          $globals.world.error("const factory not allowed", mod.get$span());
        }
        this.isConst = true;
      }
      else if (mod.get$kind() == (74)) {
        if (this.isFactory) {
          $globals.world.error("duplicate factory modifier", mod.get$span());
        }
        if (this.isConst) {
          $globals.world.error("const factory not allowed", mod.get$span());
        }
        if (this.isStatic) {
          $globals.world.error("static factory not allowed", mod.get$span());
        }
        this.isFactory = true;
      }
      else if (mod.get$kind() == (71)) {
        if (this.isAbstract) {
          if (this.declaringType.get$isClass()) {
            $globals.world.error("duplicate abstract modifier", mod.get$span());
          }
          else if (!this.get$isCallMethod()) {
            $globals.world.error("abstract modifier not allowed on interface members", mod.get$span());
          }
        }
        this.isAbstract = true;
      }
      else {
        $globals.world.error(("" + mod + " modifier not allowed on method"), mod.get$span());
      }
    }
  }
  if (this.isFactory) {
    this.isStatic = true;
  }
  if (this.get$isOperator() && this.isStatic && !this.get$isCallMethod()) {
    $globals.world.error(("operator method may not be static \"" + this.name + "\""), this.get$span());
  }
  if (this.isAbstract) {
    if (this.definition.body != null && !(this.declaringType.get$definition() instanceof FunctionTypeDefinition)) {
      $globals.world.error("abstract method cannot have a body", this.get$span());
    }
    if (this.isStatic && !(this.declaringType.get$definition() instanceof FunctionTypeDefinition)) {
      $globals.world.error("static method cannot be abstract", this.get$span());
    }
  }
  else {
    if (this.definition.body == null && !this.get$isConstructor() && !this.get$isNative()) {
      $globals.world.error("method needs a body", this.get$span());
    }
  }
  if (this.get$isConstructor() && !this.isFactory) {
    this.returnType = this.declaringType;
  }
  else {
    if ((this.definition.returnType instanceof SimpleTypeReference) && $eq$(this.definition.returnType.get$dynamic().get$type(), $globals.world.voidType)) {
      this.returnType = $globals.world.voidType;
    }
    else {
      this.returnType = this.resolveType(this.definition.returnType, false, !this.isStatic);
    }
  }
  this.parameters = [];
  var $$list = this.definition.formals;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var formal = $$i.next();
    var param = new Parameter(formal, this);
    param.resolve();
    this.parameters.add(param);
  }
  if (!this.isLambda && this.declaringType.get$isClass()) {
    this.get$library()._addMember(this);
  }
}
// ********** Code for FactoryMap **************
function FactoryMap() {
  this.factories = new HashMapImplementation();
}
FactoryMap.prototype.get$factories = function() { return this.factories; };
FactoryMap.prototype.getFactoriesFor = function(typeName) {
  var ret = this.factories.$index(typeName);
  if ($eq$(ret)) {
    ret = new HashMapImplementation();
    this.factories.$setindex(typeName, ret);
  }
  return ret;
}
FactoryMap.prototype.addFactory = function(typeName, name, member) {
  this.getFactoriesFor(typeName).$setindex(name, member);
}
FactoryMap.prototype.getFactory = function(typeName, name) {
  return this.getFactoriesFor(typeName).$index(name);
}
FactoryMap.prototype.forEach = function(f) {
  this.factories.forEach((function (_, constructors) {
    constructors.forEach((function (_, member) {
      f(member);
    })
    );
  })
  );
}
FactoryMap.prototype.isEmpty = function() {
  return this.factories.getValues().every((function (constructors) {
    return constructors.isEmpty();
  })
  );
}
// ********** Code for MemberSet **************
function MemberSet(member, isVar) {
  this.jsname = member.get$jsname();
  this.name = member.name;
  this._preparedForSet = false;
  this.isVar = isVar;
  this.members = [member];
}
MemberSet.prototype.get$name = function() { return this.name; };
MemberSet.prototype.get$members = function() { return this.members; };
MemberSet.prototype.get$jsname = function() { return this.jsname; };
MemberSet.prototype.get$isVar = function() { return this.isVar; };
MemberSet.prototype.toString = function() {
  return ("" + this.name + ":" + this.members.get$length());
}
MemberSet.prototype.add = function(member) {
  this.members.add(member);
}
MemberSet.prototype.get$isOperator = function() {
  return this.members.$index((0)).get$isOperator();
}
MemberSet.prototype.get$treatAsField = function() {
  if (this._treatAsField == null) {
    this._treatAsField = !this.isVar && this.members.every((function (m) {
      return m.get$isField();
    })
    );
  }
  return this._treatAsField;
}
MemberSet.unionTypes = function(t1, t2) {
  if (t1 == null) return t2;
  if (t2 == null) return t1;
  return Type.union(t1, t2);
}
MemberSet.prototype._get = function(context, node, target) {
  if (this.members.get$length() == (1) && !this.isVar) {
    return this.members.$index((0))._get(context, node, target);
  }
  if (this._returnTypeForGet == null) {
    var $$list = this.members;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var member = $$i.next();
      if (!member.get$canGet()) continue;
      if (!this.get$treatAsField()) member.provideGetter();
      var r = member._get(context, node, target);
      this._returnTypeForGet = MemberSet.unionTypes(this._returnTypeForGet, r.get$type());
    }
    if (this._returnTypeForGet == null) {
      $globals.world.error(("no valid getters for \"" + this.name + "\""), node.span);
    }
  }
  if (this._treatAsField) {
    return new Value(this._returnTypeForGet, ("" + target.get$code() + "." + this.jsname), node.span);
  }
  else {
    return new Value(this._returnTypeForGet, ("" + target.get$code() + ".get$" + this.jsname + "()"), node.span);
  }
}
MemberSet.prototype._set = function(context, node, target, value) {
  if (this.members.get$length() == (1) && !this.isVar) {
    return this.members.$index((0))._set(context, node, target, value);
  }
  if (!this._preparedForSet) {
    this._preparedForSet = true;
    var $$list = this.members;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var member = $$i.next();
      if (!member.get$canSet()) continue;
      if (!this.get$treatAsField()) member.provideSetter();
      var r = member._set(context, node, target, value);
    }
  }
  if (this.get$treatAsField()) {
    return new Value(value.get$type(), ("" + target.get$code() + "." + this.jsname + " = " + value.get$code()), node.span);
  }
  else {
    return new Value(value.get$type(), ("" + target.get$code() + ".set$" + this.jsname + "(" + value.get$code() + ")"), node.span);
  }
}
MemberSet.prototype.invoke = function(context, node, target, args) {
  if (this.members.get$length() == (1) && !this.isVar) {
    return this.members.$index((0)).invoke(context, node, target, args);
  }
  var invokeKey = null;
  if (this._invokes == null) {
    this._invokes = [];
    invokeKey = null;
  }
  else {
    var $$list = this._invokes;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var ik = $$i.next();
      if (ik.matches(args)) {
        invokeKey = ik;
        break;
      }
    }
  }
  if ($eq$(invokeKey)) {
    invokeKey = new InvokeKey(args);
    this._invokes.add(invokeKey);
    invokeKey.addMembers(this.members, context, target, args);
  }
  if (invokeKey.get$needsVarCall() || this.get$isOperator()) {
    if (this.name == ":call") {
      return target._varCall(context, node, args);
    }
    else if (this.get$isOperator()) {
      return this.invokeSpecial(target, args, invokeKey.get$returnType());
    }
    else {
      return this.invokeOnVar(context, node, target, args);
    }
  }
  else {
    var code = ("" + target.get$code() + "." + this.jsname + "(" + args.getCode() + ")");
    return new Value(invokeKey.get$returnType(), code, node.span);
  }
}
MemberSet.prototype.invokeSpecial = function(target, args, returnType) {
  var argsString = args.getCode();
  if (this.name == ":index" || this.name == ":setindex") {
    if (this.name == ":index") {
      $globals.world.gen.corejs.useIndex = true;
    }
    else if (this.name == ":setindex") {
      $globals.world.gen.corejs.useSetIndex = true;
    }
    return new Value(returnType, ("" + target.get$code() + "." + this.jsname + "(" + argsString + ")"), target.span);
  }
  else {
    if (argsString.get$length() > (0)) argsString = (", " + argsString);
    $globals.world.gen.corejs.useOperator(this.name);
    return new Value(returnType, ("" + this.jsname + "$(" + target.get$code() + argsString + ")"), target.span);
  }
}
MemberSet.prototype.invokeOnVar = function(context, node, target, args) {
  var $0;
  ($0 = context.get$counters()).dynamicMethodCalls = $0.dynamicMethodCalls + (1);
  var member = this.getVarMember(context, node, args);
  return member.invoke(context, node, target, args);
}
MemberSet.prototype.getVarMember = function(context, node, args) {
  if ($globals.world.objectType.varStubs == null) {
    $globals.world.objectType.varStubs = new HashMapImplementation();
  }
  var stubName = _getCallStubName(this.name, args);
  var stub = $globals.world.objectType.varStubs.$index(stubName);
  if ($eq$(stub)) {
    var mset = context.findMembers(this.name).members;
    var targets = mset.filter((function (m) {
      return m.canInvoke(context, args);
    })
    );
    stub = new VarMethodSet(this.name, stubName, targets, args, this._foldTypes(targets));
    $globals.world.objectType.varStubs.$setindex(stubName, stub);
  }
  return stub;
}
MemberSet.prototype._foldTypes = function(targets) {
  return reduce(map(targets, (function (t) {
    return t.get$returnType();
  })
  ), Type.union, $globals.world.varType);
}
MemberSet.prototype.toString$0 = MemberSet.prototype.toString;
// ********** Code for InvokeKey **************
function InvokeKey(args) {
  this.needsVarCall = false;
  this.bareArgs = args.get$bareCount();
  if (this.bareArgs != args.get$length()) {
    this.namedArgs = args.getNames();
  }
}
InvokeKey.prototype.get$returnType = function() { return this.returnType; };
InvokeKey.prototype.set$returnType = function(value) { return this.returnType = value; };
InvokeKey.prototype.get$needsVarCall = function() { return this.needsVarCall; };
InvokeKey.prototype.matches = function(args) {
  if (this.namedArgs == null) {
    if (this.bareArgs != args.get$length()) return false;
  }
  else {
    if (this.bareArgs + this.namedArgs.get$length() != args.get$length()) return false;
  }
  if (this.bareArgs != args.get$bareCount()) return false;
  if (this.namedArgs == null) return true;
  for (var i = (0);
   i < this.namedArgs.get$length(); i++) {
    if (this.namedArgs.$index(i) != args.getName(this.bareArgs + i)) return false;
  }
  return true;
}
InvokeKey.prototype.addMembers = function(members, context, target, args) {
  for (var $$i = members.iterator(); $$i.hasNext(); ) {
    var member = $$i.next();
    if (!(member.get$parameters().get$length() == this.bareArgs && this.namedArgs == null)) {
      this.needsVarCall = true;
    }
    else if ($globals.options.enableTypeChecks && member.get$isMethod() && member.needsArgumentConversion(args)) {
      this.needsVarCall = true;
    }
    else if ($eq$(member.get$library(), $globals.world.dom)) {
      var $$list = member.get$parameters();
      for (var $i0 = $$list.iterator(); $i0.hasNext(); ) {
        var p = $i0.next();
        if (p.get$type().getCallMethod() != null) {
          this.needsVarCall = true;
        }
      }
    }
    if (member.canInvoke(context, args)) {
      if (member.get$isMethod()) {
        this.returnType = MemberSet.unionTypes(this.returnType, member.get$returnType());
        member.get$declaringType().genMethod(member);
      }
      else {
        this.needsVarCall = true;
        this.returnType = $globals.world.varType;
      }
    }
  }
  if (this.returnType == null) {
    this.returnType = $globals.world.varType;
  }
}
// ********** Code for MethodCallData **************
function MethodCallData(data, method) {
  this.method = method;
  this.data = data;
}
MethodCallData.prototype.get$method = function() { return this.method; };
MethodCallData.prototype.get$_methodGenerator = function() { return this._methodGenerator; };
MethodCallData.prototype.matches = function(other) {
  return $eq$(this.method, other.method);
}
MethodCallData.prototype.run = function() {
  if (null != this._methodGenerator) return;
  this._methodGenerator = new MethodGenerator(this.method, this.data.context);
  this._methodGenerator.run();
}
MethodCallData.prototype.run$0 = MethodCallData.prototype.run;
// ********** Code for MethodData **************
function MethodData(baseMethod, context) {
  this.needsTypeParams = false;
  this._calls = [];
  this.baseMethod = baseMethod;
  this.context = context;
  this.body = this.baseMethod.definition.body;
  if (this.baseMethod.get$isConstructor()) {
    this.needsTypeParams = true;
  }
}
MethodData.prototype.get$body = function() { return this.body; };
MethodData.prototype.analyze = function() {
  var ma = new MethodAnalyzer(this.baseMethod, this.body);
  ma.analyze$1(this.context);
}
MethodData.prototype.eval = function(method, newObject, args) {
  if ((null == method ? null != (this.baseMethod) : method !== this.baseMethod)) {
    if (!this.needsTypeParams) method = this.baseMethod;
  }
  var gen = new MethodGenerator(method, this.context);
  return gen.evalBody(newObject, args);
}
MethodData.prototype.invokeCall = function(callData) {
  var $$list = this._calls;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var cd = $$i.next();
    if (cd.matches(callData)) {
      return cd.run$0();
    }
  }
  this._calls.add(callData);
  callData.run();
}
MethodData.prototype.run = function(method) {
  if (null == this.body && !method.get$isConstructor() && !method.get$isNative()) return;
  if ((null == method ? null != (this.baseMethod) : method !== this.baseMethod)) {
    if (!this.needsTypeParams) method = this.baseMethod;
  }
  var callData = new MethodCallData(this, method);
  method.declaringType.get$genericType().markUsed();
  this.invokeCall(callData);
}
MethodData.prototype.writeDefinition = function(method, writer) {
  var gen = null;
  var $$list = this._calls;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var cd = $$i.next();
    if ($eq$(cd.get$method(), method)) {
      gen = cd.get$_methodGenerator();
    }
  }
  if ($ne$(gen)) {
    if (method.definition.nativeBody != null && $eq$(method, this.baseMethod)) {
      if (method.definition.nativeBody == "") return true;
      gen.set$writer(new CodeWriter());
      gen.get$writer().write(method.definition.nativeBody);
      gen.set$_paramCode(map(method.parameters, (function (p) {
        return p.get$name();
      })
      ));
    }
    gen.writeDefinition(writer);
    return true;
  }
  else {
    return false;
  }
}
MethodData.prototype.createFunction = function(writer) {
  this.run(this.baseMethod);
  this.writeDefinition(this.baseMethod, writer);
}
MethodData.prototype.createLambda = function(node, context) {
  var lambdaGen = new MethodGenerator(this.baseMethod, context);
  if (this.baseMethod.name != "") {
    lambdaGen.get$_scope().create$3$isFinal(this.baseMethod.name, this.baseMethod.get$functionType(), this.baseMethod.definition.span, true);
    lambdaGen._pushBlock$1(this.baseMethod.definition);
  }
  this._calls.add(new MethodCallData(this, this.baseMethod));
  lambdaGen.run();
  if (this.baseMethod.name != "") {
    lambdaGen._popBlock(this.baseMethod.definition);
  }
  var writer = new CodeWriter();
  lambdaGen.writeDefinition(writer, node);
  return new Value(this.baseMethod.get$functionType(), writer.get$text(), this.baseMethod.definition.span);
}
// ********** Code for Token **************
function Token(kind, source, start, end) {
  this.end = end;
  this.kind = kind;
  this.start = start;
  this.source = source;
}
Token.prototype.get$kind = function() { return this.kind; };
Token.prototype.get$start = function() { return this.start; };
Token.prototype.get$text = function() {
  return this.source.get$text().substring(this.start, this.end);
}
Token.prototype.toString = function() {
  var kindText = TokenKind.kindToString(this.kind);
  var actualText = this.get$text();
  if ($ne$(kindText, actualText)) {
    if (actualText.get$length() > (10)) {
      actualText = $add$(actualText.substring((0), (8)), "...");
    }
    return ("" + kindText + "(" + actualText + ")");
  }
  else {
    return kindText;
  }
}
Token.prototype.get$span = function() {
  return new SourceSpan(this.source, this.start, this.end);
}
Token.prototype.toString$0 = Token.prototype.toString;
// ********** Code for LiteralToken **************
$inherits(LiteralToken, Token);
function LiteralToken(kind, source, start, end, value) {
  this.value = value;
  Token.call(this, kind, source, start, end);
}
LiteralToken.prototype.get$value = function() { return this.value; };
LiteralToken.prototype.set$value = function(value) { return this.value = value; };
// ********** Code for ErrorToken **************
$inherits(ErrorToken, Token);
function ErrorToken(kind, source, start, end, message) {
  this.message = message;
  Token.call(this, kind, source, start, end);
}
ErrorToken.prototype.get$message = function() { return this.message; };
// ********** Code for SourceFile **************
function SourceFile(filename, _text) {
  this._text = _text;
  this.filename = filename;
}
SourceFile.prototype.get$filename = function() { return this.filename; };
SourceFile.prototype.get$text = function() {
  return this._text;
}
SourceFile.prototype.get$lineStarts = function() {
  if (this._lineStarts == null) {
    var starts = [(0)];
    var index = (0);
    while ($lt$(index, this.get$text().length)) {
      index = this.get$text().indexOf("\n", index) + (1);
      if ($lte$(index, (0))) break;
      starts.add(index);
    }
    starts.add(this.get$text().length + (1));
    this._lineStarts = starts;
  }
  return this._lineStarts;
}
SourceFile.prototype.getLine = function(position) {
  var starts = this.get$lineStarts();
  for (var i = (0);
   i < starts.get$length(); i++) {
    if ($gt$(starts.$index(i), position)) return i - (1);
  }
  $globals.world.internalError("bad position");
}
SourceFile.prototype.getColumn = function(line, position) {
  return position - this.get$lineStarts().$index(line);
}
SourceFile.prototype.getLocationMessage = function(message, start, end, includeText) {
  var line = this.getLine(start);
  var column = this.getColumn(line, start);
  var buf = new StringBufferImpl(("" + this.filename + ":" + ($add$(line, (1))) + ":" + ($add$(column, (1))) + ": " + message));
  if (includeText) {
    buf.add("\n");
    var textLine;
    if ($lt$(($add$(line, (2))), this._lineStarts.get$length())) {
      textLine = this.get$text().substring(this._lineStarts.$index(line), this._lineStarts.$index($add$(line, (1))));
    }
    else {
      textLine = $add$(this.get$text().substring(this._lineStarts.$index(line)), "\n");
    }
    var toColumn = Math.min($add$(column, (end - start)), textLine.get$length());
    if ($globals.options.useColors) {
      buf.add(textLine.substring((0), column));
      buf.add($globals._RED_COLOR);
      buf.add(textLine.substring(column, toColumn));
      buf.add($globals._NO_COLOR);
      buf.add(textLine.substring$1(toColumn));
    }
    else {
      buf.add(textLine);
    }
    var i = (0);
    for (; $lt$(i, column); i++) {
      buf.add(" ");
    }
    if ($globals.options.useColors) buf.add($globals._RED_COLOR);
    for (; i < toColumn; i++) {
      buf.add("^");
    }
    if ($globals.options.useColors) buf.add($globals._NO_COLOR);
  }
  return buf.toString$0();
}
SourceFile.prototype.compareTo = function(other) {
  if (this.orderInLibrary != null && other.orderInLibrary != null) {
    return this.orderInLibrary - other.orderInLibrary;
  }
  else {
    return this.filename.compareTo(other.filename);
  }
}
// ********** Code for SourceSpan **************
function SourceSpan(file, start, end) {
  this.file = file;
  this.start = start;
  this.end = end;
}
SourceSpan.prototype.get$file = function() { return this.file; };
SourceSpan.prototype.get$start = function() { return this.start; };
SourceSpan.prototype.get$text = function() {
  return this.file.get$text().substring(this.start, this.end);
}
SourceSpan.prototype.toMessageString = function(message) {
  return this.file.getLocationMessage(message, this.start, this.end, true);
}
SourceSpan.prototype.get$locationText = function() {
  var line = this.file.getLine(this.start);
  var column = this.file.getColumn(line, this.start);
  return ("" + this.file.filename + ":" + ($add$(line, (1))) + ":" + ($add$(column, (1))));
}
SourceSpan.prototype.compareTo = function(other) {
  if ($eq$(this.file, other.file)) {
    var d = this.start - other.start;
    return d == (0) ? (this.end - other.end) : d;
  }
  return this.file.compareTo(other.file);
}
// ********** Code for InterpStack **************
function InterpStack(previous, quote, isMultiline) {
  this.quote = quote;
  this.isMultiline = isMultiline;
  this.depth = (-1);
  this.previous = previous;
}
InterpStack.prototype.set$previous = function(value) { return this.previous = value; };
InterpStack.prototype.get$quote = function() { return this.quote; };
InterpStack.prototype.get$isMultiline = function() { return this.isMultiline; };
InterpStack.prototype.get$depth = function() { return this.depth; };
InterpStack.prototype.pop = function() {
  return this.previous;
}
InterpStack.push = function(stack, quote, isMultiline) {
  var newStack = new InterpStack(stack, quote, isMultiline);
  if (stack != null) newStack.set$previous(stack);
  return newStack;
}
// ********** Code for TokenizerHelpers **************
function TokenizerHelpers() {

}
TokenizerHelpers.isIdentifierStart = function(c) {
  return ((c >= (97) && c <= (122)) || (c >= (65) && c <= (90)) || c == (95));
}
TokenizerHelpers.isDigit = function(c) {
  return (c >= (48) && c <= (57));
}
TokenizerHelpers.isIdentifierPart = function(c) {
  return (TokenizerHelpers.isIdentifierStart(c) || TokenizerHelpers.isDigit(c) || c == (36));
}
TokenizerHelpers.isInterpIdentifierPart = function(c) {
  return (TokenizerHelpers.isIdentifierStart(c) || TokenizerHelpers.isDigit(c));
}
// ********** Code for TokenizerBase **************
$inherits(TokenizerBase, TokenizerHelpers);
function TokenizerBase(_source, _skipWhitespace, index) {
  this._lang_index = index;
  this._skipWhitespace = _skipWhitespace;
  this._source = _source;
  TokenizerHelpers.call(this);
  this._text = this._source.get$text();
}
TokenizerBase.prototype._nextChar = function() {
  if (this._lang_index < this._text.length) {
    return this._text.charCodeAt(this._lang_index++);
  }
  else {
    return (0);
  }
}
TokenizerBase.prototype._peekChar = function() {
  if (this._lang_index < this._text.length) {
    return this._text.charCodeAt(this._lang_index);
  }
  else {
    return (0);
  }
}
TokenizerBase.prototype._maybeEatChar = function(ch) {
  if (this._lang_index < this._text.length) {
    if (this._text.charCodeAt(this._lang_index) == ch) {
      this._lang_index++;
      return true;
    }
    else {
      return false;
    }
  }
  else {
    return false;
  }
}
TokenizerBase.prototype._finishToken = function(kind) {
  return new Token(kind, this._source, this._startIndex, this._lang_index);
}
TokenizerBase.prototype._errorToken = function(message) {
  return new ErrorToken((65), this._source, this._startIndex, this._lang_index, message);
}
TokenizerBase.prototype.finishWhitespace = function() {
  this._lang_index--;
  while (this._lang_index < this._text.length) {
    var ch = this._text.charCodeAt(this._lang_index++);
    if ($eq$(ch, (32)) || $eq$(ch, (9)) || $eq$(ch, (13))) {
    }
    else if ($eq$(ch, (10))) {
      if (!this._skipWhitespace) {
        return this._finishToken((63));
      }
    }
    else {
      this._lang_index--;
      if (this._skipWhitespace) {
        return this.next();
      }
      else {
        return this._finishToken((63));
      }
    }
  }
  return this._finishToken((1));
}
TokenizerBase.prototype.finishHashBang = function() {
  while (true) {
    var ch = this._nextChar();
    if (ch == (0) || ch == (10) || ch == (13)) {
      return this._finishToken((13));
    }
  }
}
TokenizerBase.prototype.finishSingleLineComment = function() {
  while (true) {
    var ch = this._nextChar();
    if (ch == (0) || ch == (10) || ch == (13)) {
      if (this._skipWhitespace) {
        return this.next();
      }
      else {
        return this._finishToken((64));
      }
    }
  }
}
TokenizerBase.prototype.finishMultiLineComment = function() {
  var nesting = (1);
  do {
    var ch = this._nextChar();
    if (ch == (0)) {
      return this._errorToken();
    }
    else if (ch == (42)) {
      if (this._maybeEatChar((47))) {
        nesting--;
      }
    }
    else if (ch == (47)) {
      if (this._maybeEatChar((42))) {
        nesting++;
      }
    }
  }
  while (nesting > (0))
  if (this._skipWhitespace) {
    return this.next();
  }
  else {
    return this._finishToken((64));
  }
}
TokenizerBase.prototype.eatDigits = function() {
  while (this._lang_index < this._text.length) {
    if (TokenizerHelpers.isDigit(this._text.charCodeAt(this._lang_index))) {
      this._lang_index++;
    }
    else {
      return;
    }
  }
}
TokenizerBase._hexDigit = function(c) {
  if (c >= (48) && c <= (57)) {
    return c - (48);
  }
  else if (c >= (97) && c <= (102)) {
    return c - (87);
  }
  else if (c >= (65) && c <= (70)) {
    return c - (55);
  }
  else {
    return (-1);
  }
}
TokenizerBase.prototype.readHex = function(hexLength) {
  var maxIndex;
  if (null == hexLength) {
    maxIndex = this._text.length - (1);
  }
  else {
    maxIndex = this._lang_index + hexLength;
    if (maxIndex >= this._text.length) return (-1);
  }
  var result = (0);
  while (this._lang_index < maxIndex) {
    var digit = TokenizerBase._hexDigit(this._text.charCodeAt(this._lang_index));
    if ($eq$(digit, (-1))) {
      if (null == hexLength) {
        return result;
      }
      else {
        return (-1);
      }
    }
    TokenizerBase._hexDigit(this._text.charCodeAt(this._lang_index));
    result = $add$(($mul$(result, (16))), digit);
    this._lang_index++;
  }
  return result;
}
TokenizerBase.prototype.finishHex = function() {
  var value = this.readHex();
  return new LiteralToken((61), this._source, this._startIndex, this._lang_index, value);
}
TokenizerBase.prototype.finishNumber = function() {
  this.eatDigits();
  if (this._peekChar() == (46)) {
    this._nextChar();
    if (TokenizerHelpers.isDigit(this._peekChar())) {
      this.eatDigits();
      return this.finishNumberExtra((62));
    }
    else {
      this._lang_index--;
    }
  }
  return this.finishNumberExtra((60));
}
TokenizerBase.prototype.finishNumberExtra = function(kind) {
  if (this._maybeEatChar((101)) || this._maybeEatChar((69))) {
    kind = (62);
    this._maybeEatChar((45));
    this._maybeEatChar((43));
    this.eatDigits();
  }
  if (this._peekChar() != (0) && TokenizerHelpers.isIdentifierStart(this._peekChar())) {
    this._nextChar();
    return this._errorToken("illegal character in number");
  }
  return this._finishToken(kind);
}
TokenizerBase.prototype._makeStringToken = function(buf, isPart) {
  var s = Strings.String$fromCharCodes$factory(buf);
  var kind = isPart ? (59) : (58);
  return new LiteralToken(kind, this._source, this._startIndex, this._lang_index, s);
}
TokenizerBase.prototype._makeRawStringToken = function(isMultiline) {
  var s;
  if (isMultiline) {
    var start = this._startIndex + (4);
    if (this._source.get$text()[start] == "\n") start++;
    s = this._source.get$text().substring(start, this._lang_index - (3));
  }
  else {
    s = this._source.get$text().substring(this._startIndex + (2), this._lang_index - (1));
  }
  return new LiteralToken((58), this._source, this._startIndex, this._lang_index, s);
}
TokenizerBase.prototype.finishMultilineString = function(quote) {
  var buf = [];
  while (true) {
    var ch = this._nextChar();
    if (ch == (0)) {
      return this._errorToken();
    }
    else if (ch == quote) {
      if (this._maybeEatChar(quote)) {
        if (this._maybeEatChar(quote)) {
          return this._makeStringToken(buf, false);
        }
        buf.add(quote);
      }
      buf.add(quote);
    }
    else if (ch == (36)) {
      this._interpStack = InterpStack.push(this._interpStack, quote, true);
      return this._makeStringToken(buf, true);
    }
    else if (ch == (92)) {
      var escapeVal = this.readEscapeSequence();
      if ($eq$(escapeVal, (-1))) {
        return this._errorToken("invalid hex escape sequence");
      }
      else {
        buf.add(escapeVal);
      }
    }
    else {
      buf.add(ch);
    }
  }
}
TokenizerBase.prototype._finishOpenBrace = function() {
  var $0;
  if (this._interpStack != null) {
    if (this._interpStack.depth == (-1)) {
      this._interpStack.depth = (1);
    }
    else {
      ($0 = this._interpStack).depth = $0.depth + (1);
    }
  }
  return this._finishToken((6));
}
TokenizerBase.prototype._finishCloseBrace = function() {
  var $0;
  if (this._interpStack != null) {
    ($0 = this._interpStack).depth = $0.depth - (1);
  }
  return this._finishToken((7));
}
TokenizerBase.prototype.finishString = function(quote) {
  if (this._maybeEatChar(quote)) {
    if (this._maybeEatChar(quote)) {
      this._maybeEatChar((10));
      return this.finishMultilineString(quote);
    }
    else {
      return this._makeStringToken(new Array(), false);
    }
  }
  return this.finishStringBody(quote);
}
TokenizerBase.prototype.finishRawString = function(quote) {
  if (this._maybeEatChar(quote)) {
    if (this._maybeEatChar(quote)) {
      return this.finishMultilineRawString(quote);
    }
    else {
      return this._makeStringToken([], false);
    }
  }
  while (true) {
    var ch = this._nextChar();
    if (ch == quote) {
      return this._makeRawStringToken(false);
    }
    else if (ch == (0)) {
      return this._errorToken();
    }
  }
}
TokenizerBase.prototype.finishMultilineRawString = function(quote) {
  while (true) {
    var ch = this._nextChar();
    if (ch == (0)) {
      return this._errorToken();
    }
    else if (ch == quote && this._maybeEatChar(quote) && this._maybeEatChar(quote)) {
      return this._makeRawStringToken(true);
    }
  }
}
TokenizerBase.prototype.finishStringBody = function(quote) {
  var buf = new Array();
  while (true) {
    var ch = this._nextChar();
    if (ch == quote) {
      return this._makeStringToken(buf, false);
    }
    else if (ch == (36)) {
      this._interpStack = InterpStack.push(this._interpStack, quote, false);
      return this._makeStringToken(buf, true);
    }
    else if (ch == (0)) {
      return this._errorToken();
    }
    else if (ch == (92)) {
      var escapeVal = this.readEscapeSequence();
      if ($eq$(escapeVal, (-1))) {
        return this._errorToken("invalid hex escape sequence");
      }
      else {
        buf.add(escapeVal);
      }
    }
    else {
      buf.add(ch);
    }
  }
}
TokenizerBase.prototype.readEscapeSequence = function() {
  var ch = this._nextChar();
  var hexValue;
  switch (ch) {
    case (110):

      return (10);

    case (114):

      return (13);

    case (102):

      return (12);

    case (98):

      return (8);

    case (116):

      return (9);

    case (118):

      return (11);

    case (120):

      hexValue = this.readHex((2));
      break;

    case (117):

      if (this._maybeEatChar((123))) {
        hexValue = this.readHex();
        if (!this._maybeEatChar((125))) {
          return (-1);
        }
        else {
          break;
        }
      }
      else {
        hexValue = this.readHex((4));
        break;
      }

    default:

      return ch;

  }
  if (hexValue == (-1)) return (-1);
  if (hexValue < (55296) || hexValue > (57343) && hexValue <= (65535)) {
    return hexValue;
  }
  else if (hexValue <= (1114111)) {
    $globals.world.fatal("unicode values greater than 2 bytes not implemented yet");
    return (-1);
  }
  else {
    return (-1);
  }
}
TokenizerBase.prototype.finishDot = function() {
  if (TokenizerHelpers.isDigit(this._peekChar())) {
    this.eatDigits();
    return this.finishNumberExtra((62));
  }
  else {
    return this._finishToken((14));
  }
}
TokenizerBase.prototype.finishIdentifier = function(ch) {
  if (this._interpStack != null && this._interpStack.depth == (-1)) {
    this._interpStack.depth = (0);
    if (ch == (36)) {
      return this._errorToken("illegal character after $ in string interpolation");
    }
    while (this._lang_index < this._text.length) {
      if (!TokenizerHelpers.isInterpIdentifierPart(this._text.charCodeAt(this._lang_index++))) {
        this._lang_index--;
        break;
      }
    }
  }
  else {
    while (this._lang_index < this._text.length) {
      if (!TokenizerHelpers.isIdentifierPart(this._text.charCodeAt(this._lang_index++))) {
        this._lang_index--;
        break;
      }
    }
  }
  var kind = this.getIdentifierKind();
  if (kind == (70)) {
    return this._finishToken((70));
  }
  else {
    return this._finishToken(kind);
  }
}
// ********** Code for Tokenizer **************
$inherits(Tokenizer, TokenizerBase);
function Tokenizer(source, skipWhitespace, index) {
  TokenizerBase.call(this, source, skipWhitespace, index);
}
Tokenizer.prototype.next = function() {
  this._startIndex = this._lang_index;
  if (this._interpStack != null && this._interpStack.depth == (0)) {
    var istack = this._interpStack;
    this._interpStack = this._interpStack.pop();
    if (istack.get$isMultiline()) {
      return this.finishMultilineString(istack.get$quote());
    }
    else {
      return this.finishStringBody(istack.get$quote());
    }
  }
  var ch;
  ch = this._nextChar();
  switch (ch) {
    case (0):

      return this._finishToken((1));

    case (32):
    case (9):
    case (10):
    case (13):

      return this.finishWhitespace();

    case (33):

      if (this._maybeEatChar((61))) {
        if (this._maybeEatChar((61))) {
          return this._finishToken((51));
        }
        else {
          return this._finishToken((49));
        }
      }
      else {
        return this._finishToken((19));
      }

    case (34):

      return this.finishString((34));

    case (35):

      if (this._maybeEatChar((33))) {
        return this.finishHashBang();
      }
      else {
        return this._finishToken((12));
      }

    case (36):

      if (this._maybeEatChar((34))) {
        return this.finishString((34));
      }
      else if (this._maybeEatChar((39))) {
        return this.finishString((39));
      }
      else {
        return this.finishIdentifier((36));
      }

    case (37):

      if (this._maybeEatChar((61))) {
        return this._finishToken((32));
      }
      else {
        return this._finishToken((47));
      }

    case (38):

      if (this._maybeEatChar((38))) {
        return this._finishToken((35));
      }
      else if (this._maybeEatChar((61))) {
        return this._finishToken((23));
      }
      else {
        return this._finishToken((38));
      }

    case (39):

      return this.finishString((39));

    case (40):

      return this._finishToken((2));

    case (41):

      return this._finishToken((3));

    case (42):

      if (this._maybeEatChar((61))) {
        return this._finishToken((29));
      }
      else {
        return this._finishToken((44));
      }

    case (43):

      if (this._maybeEatChar((43))) {
        return this._finishToken((16));
      }
      else if (this._maybeEatChar((61))) {
        return this._finishToken((27));
      }
      else {
        return this._finishToken((42));
      }

    case (44):

      return this._finishToken((11));

    case (45):

      if (this._maybeEatChar((45))) {
        return this._finishToken((17));
      }
      else if (this._maybeEatChar((61))) {
        return this._finishToken((28));
      }
      else {
        return this._finishToken((43));
      }

    case (46):

      if (this._maybeEatChar((46))) {
        if (this._maybeEatChar((46))) {
          return this._finishToken((15));
        }
        else {
          return this._errorToken();
        }
      }
      else {
        return this.finishDot();
      }

    case (47):

      if (this._maybeEatChar((42))) {
        return this.finishMultiLineComment();
      }
      else if (this._maybeEatChar((47))) {
        return this.finishSingleLineComment();
      }
      else if (this._maybeEatChar((61))) {
        return this._finishToken((30));
      }
      else {
        return this._finishToken((45));
      }

    case (48):

      if (this._maybeEatChar((88))) {
        return this.finishHex();
      }
      else if (this._maybeEatChar((120))) {
        return this.finishHex();
      }
      else {
        return this.finishNumber();
      }

    case (58):

      return this._finishToken((8));

    case (59):

      return this._finishToken((10));

    case (60):

      if (this._maybeEatChar((60))) {
        if (this._maybeEatChar((61))) {
          return this._finishToken((24));
        }
        else {
          return this._finishToken((39));
        }
      }
      else if (this._maybeEatChar((61))) {
        return this._finishToken((54));
      }
      else {
        return this._finishToken((52));
      }

    case (61):

      if (this._maybeEatChar((61))) {
        if (this._maybeEatChar((61))) {
          return this._finishToken((50));
        }
        else {
          return this._finishToken((48));
        }
      }
      else if (this._maybeEatChar((62))) {
        return this._finishToken((9));
      }
      else {
        return this._finishToken((20));
      }

    case (62):

      if (this._maybeEatChar((61))) {
        return this._finishToken((55));
      }
      else if (this._maybeEatChar((62))) {
        if (this._maybeEatChar((61))) {
          return this._finishToken((25));
        }
        else if (this._maybeEatChar((62))) {
          if (this._maybeEatChar((61))) {
            return this._finishToken((26));
          }
          else {
            return this._finishToken((41));
          }
        }
        else {
          return this._finishToken((40));
        }
      }
      else {
        return this._finishToken((53));
      }

    case (63):

      return this._finishToken((33));

    case (64):

      if (this._maybeEatChar((34))) {
        return this.finishRawString((34));
      }
      else if (this._maybeEatChar((39))) {
        return this.finishRawString((39));
      }
      else {
        return this._errorToken();
      }

    case (91):

      if (this._maybeEatChar((93))) {
        if (this._maybeEatChar((61))) {
          return this._finishToken((57));
        }
        else {
          return this._finishToken((56));
        }
      }
      else {
        return this._finishToken((4));
      }

    case (93):

      return this._finishToken((5));

    case (94):

      if (this._maybeEatChar((61))) {
        return this._finishToken((22));
      }
      else {
        return this._finishToken((37));
      }

    case (123):

      return this._finishOpenBrace();

    case (124):

      if (this._maybeEatChar((61))) {
        return this._finishToken((21));
      }
      else if (this._maybeEatChar((124))) {
        return this._finishToken((34));
      }
      else {
        return this._finishToken((36));
      }

    case (125):

      return this._finishCloseBrace();

    case (126):

      if (this._maybeEatChar((47))) {
        if (this._maybeEatChar((61))) {
          return this._finishToken((31));
        }
        else {
          return this._finishToken((46));
        }
      }
      else {
        return this._finishToken((18));
      }

    default:

      if (TokenizerHelpers.isIdentifierStart(ch)) {
        return this.finishIdentifier(ch);
      }
      else if (TokenizerHelpers.isDigit(ch)) {
        return this.finishNumber();
      }
      else {
        return this._errorToken();
      }

  }
}
Tokenizer.prototype.getIdentifierKind = function() {
  var i0 = this._startIndex;
  var ch;
  switch ($sub$(this._lang_index, i0)) {
    case (2):

      ch = this._text.charCodeAt(i0);
      if (ch == (100)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (111)) return (95);
      }
      else if (ch == (105)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (102)) {
          return (102);
        }
        else if (ch == (110)) {
          return (103);
        }
        else if (ch == (115)) {
          return (104);
        }
      }
      return (70);

    case (3):

      ch = this._text.charCodeAt(i0);
      if (ch == (102)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (111) && this._text.charCodeAt($add$(i0, (2))) == (114)) return (101);
      }
      else if (ch == (103)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (101) && this._text.charCodeAt($add$(i0, (2))) == (116)) return (75);
      }
      else if (ch == (110)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (101) && this._text.charCodeAt($add$(i0, (2))) == (119)) return (105);
      }
      else if (ch == (115)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (101) && this._text.charCodeAt($add$(i0, (2))) == (116)) return (83);
      }
      else if (ch == (116)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (114) && this._text.charCodeAt($add$(i0, (2))) == (121)) return (113);
      }
      else if (ch == (118)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (97) && this._text.charCodeAt($add$(i0, (2))) == (114)) return (114);
      }
      return (70);

    case (4):

      ch = this._text.charCodeAt(i0);
      if (ch == (99)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (97)) {
          ch = this._text.charCodeAt($add$(i0, (2)));
          if (ch == (108)) {
            if (this._text.charCodeAt($add$(i0, (3))) == (108)) return (73);
          }
          else if (ch == (115)) {
            if (this._text.charCodeAt($add$(i0, (3))) == (101)) return (89);
          }
        }
      }
      else if (ch == (101)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (108) && this._text.charCodeAt($add$(i0, (2))) == (115) && this._text.charCodeAt($add$(i0, (3))) == (101)) return (96);
      }
      else if (ch == (110)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (117) && this._text.charCodeAt($add$(i0, (2))) == (108) && this._text.charCodeAt($add$(i0, (3))) == (108)) return (106);
      }
      else if (ch == (116)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (104)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (105) && this._text.charCodeAt($add$(i0, (3))) == (115)) return (110);
        }
        else if (ch == (114)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (117) && this._text.charCodeAt($add$(i0, (3))) == (101)) return (112);
        }
      }
      else if (ch == (118)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (111) && this._text.charCodeAt($add$(i0, (2))) == (105) && this._text.charCodeAt($add$(i0, (3))) == (100)) return (115);
      }
      return (70);

    case (5):

      ch = this._text.charCodeAt(i0);
      if (ch == (97)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (119) && this._text.charCodeAt($add$(i0, (2))) == (97) && this._text.charCodeAt($add$(i0, (3))) == (105) && this._text.charCodeAt($add$(i0, (4))) == (116)) return (87);
      }
      else if (ch == (98)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (114) && this._text.charCodeAt($add$(i0, (2))) == (101) && this._text.charCodeAt($add$(i0, (3))) == (97) && this._text.charCodeAt($add$(i0, (4))) == (107)) return (88);
      }
      else if (ch == (99)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (97)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (116) && this._text.charCodeAt($add$(i0, (3))) == (99) && this._text.charCodeAt($add$(i0, (4))) == (104)) return (90);
        }
        else if (ch == (108)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (97) && this._text.charCodeAt($add$(i0, (3))) == (115) && this._text.charCodeAt($add$(i0, (4))) == (115)) return (91);
        }
        else if (ch == (111)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (110) && this._text.charCodeAt($add$(i0, (3))) == (115) && this._text.charCodeAt($add$(i0, (4))) == (116)) return (92);
        }
      }
      else if (ch == (102)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (97)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (108) && this._text.charCodeAt($add$(i0, (3))) == (115) && this._text.charCodeAt($add$(i0, (4))) == (101)) return (98);
        }
        else if (ch == (105)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (110) && this._text.charCodeAt($add$(i0, (3))) == (97) && this._text.charCodeAt($add$(i0, (4))) == (108)) return (99);
        }
      }
      else if (ch == (115)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (117) && this._text.charCodeAt($add$(i0, (2))) == (112) && this._text.charCodeAt($add$(i0, (3))) == (101) && this._text.charCodeAt($add$(i0, (4))) == (114)) return (108);
      }
      else if (ch == (116)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (104) && this._text.charCodeAt($add$(i0, (2))) == (114) && this._text.charCodeAt($add$(i0, (3))) == (111) && this._text.charCodeAt($add$(i0, (4))) == (119)) return (111);
      }
      else if (ch == (119)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (104) && this._text.charCodeAt($add$(i0, (2))) == (105) && this._text.charCodeAt($add$(i0, (3))) == (108) && this._text.charCodeAt($add$(i0, (4))) == (101)) return (116);
      }
      return (70);

    case (6):

      ch = this._text.charCodeAt(i0);
      if (ch == (97)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (115) && this._text.charCodeAt($add$(i0, (2))) == (115) && this._text.charCodeAt($add$(i0, (3))) == (101) && this._text.charCodeAt($add$(i0, (4))) == (114) && this._text.charCodeAt($add$(i0, (5))) == (116)) return (72);
      }
      else if (ch == (105)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (109) && this._text.charCodeAt($add$(i0, (2))) == (112) && this._text.charCodeAt($add$(i0, (3))) == (111) && this._text.charCodeAt($add$(i0, (4))) == (114) && this._text.charCodeAt($add$(i0, (5))) == (116)) return (77);
      }
      else if (ch == (110)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (97)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (116) && this._text.charCodeAt($add$(i0, (3))) == (105) && this._text.charCodeAt($add$(i0, (4))) == (118) && this._text.charCodeAt($add$(i0, (5))) == (101)) return (80);
        }
        else if (ch == (101)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (103) && this._text.charCodeAt($add$(i0, (3))) == (97) && this._text.charCodeAt($add$(i0, (4))) == (116) && this._text.charCodeAt($add$(i0, (5))) == (101)) return (81);
        }
      }
      else if (ch == (114)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (101) && this._text.charCodeAt($add$(i0, (2))) == (116) && this._text.charCodeAt($add$(i0, (3))) == (117) && this._text.charCodeAt($add$(i0, (4))) == (114) && this._text.charCodeAt($add$(i0, (5))) == (110)) return (107);
      }
      else if (ch == (115)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (111)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (117) && this._text.charCodeAt($add$(i0, (3))) == (114) && this._text.charCodeAt($add$(i0, (4))) == (99) && this._text.charCodeAt($add$(i0, (5))) == (101)) return (84);
        }
        else if (ch == (116)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (97) && this._text.charCodeAt($add$(i0, (3))) == (116) && this._text.charCodeAt($add$(i0, (4))) == (105) && this._text.charCodeAt($add$(i0, (5))) == (99)) return (85);
        }
        else if (ch == (119)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (105) && this._text.charCodeAt($add$(i0, (3))) == (116) && this._text.charCodeAt($add$(i0, (4))) == (99) && this._text.charCodeAt($add$(i0, (5))) == (104)) return (109);
        }
      }
      return (70);

    case (7):

      ch = this._text.charCodeAt(i0);
      if (ch == (100)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (101) && this._text.charCodeAt($add$(i0, (2))) == (102) && this._text.charCodeAt($add$(i0, (3))) == (97) && this._text.charCodeAt($add$(i0, (4))) == (117) && this._text.charCodeAt($add$(i0, (5))) == (108) && this._text.charCodeAt($add$(i0, (6))) == (116)) return (94);
      }
      else if (ch == (101)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (120) && this._text.charCodeAt($add$(i0, (2))) == (116) && this._text.charCodeAt($add$(i0, (3))) == (101) && this._text.charCodeAt($add$(i0, (4))) == (110) && this._text.charCodeAt($add$(i0, (5))) == (100) && this._text.charCodeAt($add$(i0, (6))) == (115)) return (97);
      }
      else if (ch == (102)) {
        ch = this._text.charCodeAt($add$(i0, (1)));
        if (ch == (97)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (99) && this._text.charCodeAt($add$(i0, (3))) == (116) && this._text.charCodeAt($add$(i0, (4))) == (111) && this._text.charCodeAt($add$(i0, (5))) == (114) && this._text.charCodeAt($add$(i0, (6))) == (121)) return (74);
        }
        else if (ch == (105)) {
          if (this._text.charCodeAt($add$(i0, (2))) == (110) && this._text.charCodeAt($add$(i0, (3))) == (97) && this._text.charCodeAt($add$(i0, (4))) == (108) && this._text.charCodeAt($add$(i0, (5))) == (108) && this._text.charCodeAt($add$(i0, (6))) == (121)) return (100);
        }
      }
      else if (ch == (108)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (105) && this._text.charCodeAt($add$(i0, (2))) == (98) && this._text.charCodeAt($add$(i0, (3))) == (114) && this._text.charCodeAt($add$(i0, (4))) == (97) && this._text.charCodeAt($add$(i0, (5))) == (114) && this._text.charCodeAt($add$(i0, (6))) == (121)) return (79);
      }
      else if (ch == (116)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (121) && this._text.charCodeAt($add$(i0, (2))) == (112) && this._text.charCodeAt($add$(i0, (3))) == (101) && this._text.charCodeAt($add$(i0, (4))) == (100) && this._text.charCodeAt($add$(i0, (5))) == (101) && this._text.charCodeAt($add$(i0, (6))) == (102)) return (86);
      }
      return (70);

    case (8):

      ch = this._text.charCodeAt(i0);
      if (ch == (97)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (98) && this._text.charCodeAt($add$(i0, (2))) == (115) && this._text.charCodeAt($add$(i0, (3))) == (116) && this._text.charCodeAt($add$(i0, (4))) == (114) && this._text.charCodeAt($add$(i0, (5))) == (97) && this._text.charCodeAt($add$(i0, (6))) == (99) && this._text.charCodeAt($add$(i0, (7))) == (116)) return (71);
      }
      else if (ch == (99)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (111) && this._text.charCodeAt($add$(i0, (2))) == (110) && this._text.charCodeAt($add$(i0, (3))) == (116) && this._text.charCodeAt($add$(i0, (4))) == (105) && this._text.charCodeAt($add$(i0, (5))) == (110) && this._text.charCodeAt($add$(i0, (6))) == (117) && this._text.charCodeAt($add$(i0, (7))) == (101)) return (93);
      }
      else if (ch == (111)) {
        if (this._text.charCodeAt($add$(i0, (1))) == (112) && this._text.charCodeAt($add$(i0, (2))) == (101) && this._text.charCodeAt($add$(i0, (3))) == (114) && this._text.charCodeAt($add$(i0, (4))) == (97) && this._text.charCodeAt($add$(i0, (5))) == (116) && this._text.charCodeAt($add$(i0, (6))) == (111) && this._text.charCodeAt($add$(i0, (7))) == (114)) return (82);
      }
      return (70);

    case (9):

      if (this._text.charCodeAt(i0) == (105) && this._text.charCodeAt($add$(i0, (1))) == (110) && this._text.charCodeAt($add$(i0, (2))) == (116) && this._text.charCodeAt($add$(i0, (3))) == (101) && this._text.charCodeAt($add$(i0, (4))) == (114) && this._text.charCodeAt($add$(i0, (5))) == (102) && this._text.charCodeAt($add$(i0, (6))) == (97) && this._text.charCodeAt($add$(i0, (7))) == (99) && this._text.charCodeAt($add$(i0, (8))) == (101)) return (78);
      return (70);

    case (10):

      if (this._text.charCodeAt(i0) == (105) && this._text.charCodeAt($add$(i0, (1))) == (109) && this._text.charCodeAt($add$(i0, (2))) == (112) && this._text.charCodeAt($add$(i0, (3))) == (108) && this._text.charCodeAt($add$(i0, (4))) == (101) && this._text.charCodeAt($add$(i0, (5))) == (109) && this._text.charCodeAt($add$(i0, (6))) == (101) && this._text.charCodeAt($add$(i0, (7))) == (110) && this._text.charCodeAt($add$(i0, (8))) == (116) && this._text.charCodeAt($add$(i0, (9))) == (115)) return (76);
      return (70);

    default:

      return (70);

  }
}
// ********** Code for TokenKind **************
function TokenKind() {}
TokenKind.kindToString = function(kind) {
  switch (kind) {
    case (1):

      return "end of file";

    case (2):

      return "(";

    case (3):

      return ")";

    case (4):

      return "[";

    case (5):

      return "]";

    case (6):

      return "{";

    case (7):

      return "}";

    case (8):

      return ":";

    case (9):

      return "=>";

    case (10):

      return ";";

    case (11):

      return ",";

    case (12):

      return "#";

    case (13):

      return "#!";

    case (14):

      return ".";

    case (15):

      return "...";

    case (16):

      return "++";

    case (17):

      return "--";

    case (18):

      return "~";

    case (19):

      return "!";

    case (20):

      return "=";

    case (21):

      return "|=";

    case (22):

      return "^=";

    case (23):

      return "&=";

    case (24):

      return "<<=";

    case (25):

      return ">>=";

    case (26):

      return ">>>=";

    case (27):

      return "+=";

    case (28):

      return "-=";

    case (29):

      return "*=";

    case (30):

      return "/=";

    case (31):

      return "~/=";

    case (32):

      return "%=";

    case (33):

      return "?";

    case (34):

      return "||";

    case (35):

      return "&&";

    case (36):

      return "|";

    case (37):

      return "^";

    case (38):

      return "&";

    case (39):

      return "<<";

    case (40):

      return ">>";

    case (41):

      return ">>>";

    case (42):

      return "+";

    case (43):

      return "-";

    case (44):

      return "*";

    case (45):

      return "/";

    case (46):

      return "~/";

    case (47):

      return "%";

    case (48):

      return "==";

    case (49):

      return "!=";

    case (50):

      return "===";

    case (51):

      return "!==";

    case (52):

      return "<";

    case (53):

      return ">";

    case (54):

      return "<=";

    case (55):

      return ">=";

    case (56):

      return "[]";

    case (57):

      return "[]=";

    case (58):

      return "string";

    case (59):

      return "string part";

    case (60):

      return "integer";

    case (61):

      return "hex integer";

    case (62):

      return "double";

    case (63):

      return "whitespace";

    case (64):

      return "comment";

    case (65):

      return "error";

    case (66):

      return "incomplete string";

    case (67):

      return "incomplete comment";

    case (68):

      return "incomplete multiline string dq";

    case (69):

      return "incomplete multiline string sq";

    case (70):

      return "identifier";

    case (71):

      return "pseudo-keyword 'abstract'";

    case (72):

      return "pseudo-keyword 'assert'";

    case (73):

      return "pseudo-keyword 'call'";

    case (74):

      return "pseudo-keyword 'factory'";

    case (75):

      return "pseudo-keyword 'get'";

    case (76):

      return "pseudo-keyword 'implements'";

    case (77):

      return "pseudo-keyword 'import'";

    case (78):

      return "pseudo-keyword 'interface'";

    case (79):

      return "pseudo-keyword 'library'";

    case (80):

      return "pseudo-keyword 'native'";

    case (81):

      return "pseudo-keyword 'negate'";

    case (82):

      return "pseudo-keyword 'operator'";

    case (83):

      return "pseudo-keyword 'set'";

    case (84):

      return "pseudo-keyword 'source'";

    case (85):

      return "pseudo-keyword 'static'";

    case (86):

      return "pseudo-keyword 'typedef'";

    case (87):

      return "keyword 'await'";

    case (88):

      return "keyword 'break'";

    case (89):

      return "keyword 'case'";

    case (90):

      return "keyword 'catch'";

    case (91):

      return "keyword 'class'";

    case (92):

      return "keyword 'const'";

    case (93):

      return "keyword 'continue'";

    case (94):

      return "keyword 'default'";

    case (95):

      return "keyword 'do'";

    case (96):

      return "keyword 'else'";

    case (97):

      return "keyword 'extends'";

    case (98):

      return "keyword 'false'";

    case (99):

      return "keyword 'final'";

    case (100):

      return "keyword 'finally'";

    case (101):

      return "keyword 'for'";

    case (102):

      return "keyword 'if'";

    case (103):

      return "keyword 'in'";

    case (104):

      return "keyword 'is'";

    case (105):

      return "keyword 'new'";

    case (106):

      return "keyword 'null'";

    case (107):

      return "keyword 'return'";

    case (108):

      return "keyword 'super'";

    case (109):

      return "keyword 'switch'";

    case (110):

      return "keyword 'this'";

    case (111):

      return "keyword 'throw'";

    case (112):

      return "keyword 'true'";

    case (113):

      return "keyword 'try'";

    case (114):

      return "keyword 'var'";

    case (115):

      return "keyword 'void'";

    case (116):

      return "keyword 'while'";

    default:

      return $add$($add$("TokenKind(", kind.toString$0()), ")");

  }
}
TokenKind.isIdentifier = function(kind) {
  return kind >= (70) && kind < (87);
}
TokenKind.infixPrecedence = function(kind) {
  switch (kind) {
    case (20):

      return (2);

    case (21):

      return (2);

    case (22):

      return (2);

    case (23):

      return (2);

    case (24):

      return (2);

    case (25):

      return (2);

    case (26):

      return (2);

    case (27):

      return (2);

    case (28):

      return (2);

    case (29):

      return (2);

    case (30):

      return (2);

    case (31):

      return (2);

    case (32):

      return (2);

    case (33):

      return (3);

    case (34):

      return (4);

    case (35):

      return (5);

    case (36):

      return (6);

    case (37):

      return (7);

    case (38):

      return (8);

    case (39):

      return (11);

    case (40):

      return (11);

    case (41):

      return (11);

    case (42):

      return (12);

    case (43):

      return (12);

    case (44):

      return (13);

    case (45):

      return (13);

    case (46):

      return (13);

    case (47):

      return (13);

    case (48):

      return (9);

    case (49):

      return (9);

    case (50):

      return (9);

    case (51):

      return (9);

    case (52):

      return (10);

    case (53):

      return (10);

    case (54):

      return (10);

    case (55):

      return (10);

    case (104):

      return (10);

    default:

      return (-1);

  }
}
TokenKind.rawOperatorFromMethod = function(name) {
  switch (name) {
    case ":bit_not":

      return "~";

    case ":bit_or":

      return "|";

    case ":bit_xor":

      return "^";

    case ":bit_and":

      return "&";

    case ":shl":

      return "<<";

    case ":sar":

      return ">>";

    case ":shr":

      return ">>>";

    case ":add":

      return "+";

    case ":sub":

      return "-";

    case ":mul":

      return "*";

    case ":div":

      return "/";

    case ":truncdiv":

      return "~/";

    case ":mod":

      return "%";

    case ":eq":

      return "==";

    case ":lt":

      return "<";

    case ":gt":

      return ">";

    case ":lte":

      return "<=";

    case ":gte":

      return ">=";

    case ":index":

      return "[]";

    case ":setindex":

      return "[]=";

    case ":ne":

      return "!=";

  }
}
TokenKind.binaryMethodName = function(kind) {
  switch (kind) {
    case (18):

      return ":bit_not";

    case (36):

      return ":bit_or";

    case (37):

      return ":bit_xor";

    case (38):

      return ":bit_and";

    case (39):

      return ":shl";

    case (40):

      return ":sar";

    case (41):

      return ":shr";

    case (42):

      return ":add";

    case (43):

      return ":sub";

    case (44):

      return ":mul";

    case (45):

      return ":div";

    case (46):

      return ":truncdiv";

    case (47):

      return ":mod";

    case (48):

      return ":eq";

    case (52):

      return ":lt";

    case (53):

      return ":gt";

    case (54):

      return ":lte";

    case (55):

      return ":gte";

    case (56):

      return ":index";

    case (57):

      return ":setindex";

  }
}
TokenKind.kindFromAssign = function(kind) {
  if (kind == (20)) return (0);
  if (kind > (20) && kind <= (32)) {
    return kind + (15);
  }
  return (-1);
}
// ********** Code for Parser **************
function Parser(source, diet, throwOnIncomplete, optionalSemicolons, startOffset) {
  this.throwOnIncomplete = throwOnIncomplete;
  this.source = source;
  this.optionalSemicolons = optionalSemicolons;
  this._recover = false;
  this._inhibitLambda = false;
  this.diet = diet;
  this._afterParensIndex = (0);
  this.tokenizer = new Tokenizer(this.source, true, startOffset);
  this._peekToken = this.tokenizer.next();
  this._afterParens = [];
}
Parser.prototype.get$enableAwait = function() {
  return $globals.experimentalAwaitPhase != null;
}
Parser.prototype.isPrematureEndOfFile = function() {
  if (this.throwOnIncomplete && this._maybeEat((1))) {
    $throw(new IncompleteSourceException(this._previousToken));
  }
  else if (this._maybeEat((1))) {
    this._error("unexpected end of file", this._peekToken.get$span());
    return true;
  }
  else {
    return false;
  }
}
Parser.prototype._recoverTo = function(kind1, kind2, kind3) {
  while (!this.isPrematureEndOfFile()) {
    var kind = this._peek();
    if (kind == kind1 || kind == kind2 || kind == kind3) {
      this._recover = false;
      return true;
    }
    this._lang_next();
  }
  return false;
}
Parser.prototype._peek = function() {
  return this._peekToken.kind;
}
Parser.prototype._lang_next = function() {
  this._previousToken = this._peekToken;
  this._peekToken = this.tokenizer.next();
  return this._previousToken;
}
Parser.prototype._peekKind = function(kind) {
  return this._peekToken.kind == kind;
}
Parser.prototype._peekIdentifier = function() {
  return this._isIdentifier(this._peekToken.kind);
}
Parser.prototype._isIdentifier = function(kind) {
  return TokenKind.isIdentifier(kind) || (!this.get$enableAwait() && $eq$(kind, (87)));
}
Parser.prototype._maybeEat = function(kind) {
  if (this._peekToken.kind == kind) {
    this._previousToken = this._peekToken;
    this._peekToken = this.tokenizer.next();
    return true;
  }
  else {
    return false;
  }
}
Parser.prototype._eat = function(kind) {
  if (!this._maybeEat(kind)) {
    this._errorExpected(TokenKind.kindToString(kind));
  }
}
Parser.prototype._eatSemicolon = function() {
  if (this.optionalSemicolons && this._peekKind((1))) return;
  this._eat((10));
}
Parser.prototype._errorExpected = function(expected) {
  if (this.throwOnIncomplete) this.isPrematureEndOfFile();
  var tok = this._lang_next();
  if ((tok instanceof ErrorToken) && tok.get$message() != null) {
    this._error(tok.get$message(), tok.get$span());
  }
  else {
    this._error(("expected " + expected + ", but found " + tok), tok.get$span());
  }
}
Parser.prototype._error = function(message, location) {
  if (this._recover) return;
  if (location == null) {
    location = this._peekToken.get$span();
  }
  $globals.world.fatal(message, location);
  this._recover = true;
}
Parser.prototype._skipBlock = function() {
  var depth = (1);
  this._eat((6));
  while (true) {
    var tok = this._lang_next();
    if (tok.get$kind() == (6)) {
      depth += (1);
    }
    else if (tok.get$kind() == (7)) {
      depth -= (1);
      if (depth == (0)) return;
    }
    else if (tok.get$kind() == (1)) {
      this._error("unexpected end of file during diet parse", tok.get$span());
      return;
    }
  }
}
Parser.prototype._makeSpan = function(start) {
  return new SourceSpan(this.source, start, this._previousToken.end);
}
Parser.prototype.compilationUnit = function() {
  var ret = [];
  this._maybeEat((13));
  while (this._peekKind((12))) {
    ret.add(this.directive());
  }
  this._recover = false;
  while (!this._maybeEat((1))) {
    ret.add(this.topLevelDefinition());
  }
  this._recover = false;
  return ret;
}
Parser.prototype.directive = function() {
  var start = this._peekToken.start;
  this._eat((12));
  var name = this.identifier();
  var args = this.arguments();
  this._eatSemicolon();
  return new DirectiveDefinition(name, args, this._makeSpan(start));
}
Parser.prototype.topLevelDefinition = function() {
  switch (this._peek()) {
    case (91):

      return this.classDefinition((91));

    case (78):

      return this.classDefinition((78));

    case (86):

      return this.functionTypeAlias();

    default:

      return this.declaration(true);

  }
}
Parser.prototype.classDefinition = function(kind) {
  var start = this._peekToken.start;
  this._eat(kind);
  var name = this.identifierForType();
  var typeParams = null;
  if (this._peekKind((52))) {
    typeParams = this.typeParameters();
  }
  var _extends = null;
  if (this._maybeEat((97))) {
    _extends = this.typeList();
  }
  var _implements = null;
  if (this._maybeEat((76))) {
    _implements = this.typeList();
  }
  var _native = null;
  if (this._maybeEat((80))) {
    _native = this.maybeStringLiteral();
    if ($ne$(_native)) _native = new NativeType(_native);
  }
  var oldFactory = this._maybeEat((74));
  var defaultType = null;
  if (oldFactory || this._maybeEat((94))) {
    if (oldFactory) {
      $globals.world.warning("factory no longer supported, use \"default\" instead", this._previousToken.get$span());
    }
    var baseType = this.nameTypeReference();
    var factTypeParams = null;
    if (this._peekKind((52))) {
      factTypeParams = this.typeParameters();
    }
    defaultType = new DefaultTypeReference(oldFactory, baseType, factTypeParams, this._makeSpan(baseType.get$span().start));
  }
  var body = [];
  if (this._maybeEat((6))) {
    while (!this._maybeEat((7))) {
      body.add(this.declaration(true));
      if (this._recover) {
        if (!this._recoverTo((7), (10))) break;
        this._maybeEat((10));
      }
    }
  }
  else {
    this._errorExpected("block starting with \"{\" or \";\"");
  }
  return new TypeDefinition(kind == (91), name, typeParams, _extends, _implements, _native, defaultType, body, this._makeSpan(start));
}
Parser.prototype.functionTypeAlias = function() {
  var start = this._peekToken.start;
  this._eat((86));
  var di = this.declaredIdentifier(false);
  var typeParams = null;
  if (this._peekKind((52))) {
    typeParams = this.typeParameters();
  }
  var formals = this.formalParameterList();
  this._eatSemicolon();
  var func = new FunctionDefinition(null, di.get$type(), di.get$name(), formals, null, null, null, this._makeSpan(start));
  return new FunctionTypeDefinition(func, typeParams, this._makeSpan(start));
}
Parser.prototype.initializers = function() {
  this._inhibitLambda = true;
  var ret = [];
  do {
    ret.add(this.expression());
  }
  while (this._maybeEat((11)))
  this._inhibitLambda = false;
  return ret;
}
Parser.prototype.get$initializers = function() {
  return this.initializers.bind(this);
}
Parser.prototype.functionBody = function(inExpression) {
  var start = this._peekToken.start;
  if (this._maybeEat((9))) {
    var expr = this.expression();
    if (!inExpression) {
      this._eatSemicolon();
    }
    return new ReturnStatement(expr, this._makeSpan(start));
  }
  else if (this._peekKind((6))) {
    if (this.diet) {
      this._skipBlock();
      return new DietStatement(this._makeSpan(start));
    }
    else {
      return this.block();
    }
  }
  else if (!inExpression) {
    if (this._maybeEat((10))) {
      return null;
    }
  }
  this._error("Expected function body (neither { nor => found)");
}
Parser.prototype.finishField = function(start, modifiers, type, name, value) {
  var names = [name];
  var values = [value];
  while (this._maybeEat((11))) {
    names.add(this.identifier());
    if (this._maybeEat((20))) {
      values.add(this.expression());
    }
    else {
      values.add();
    }
  }
  this._eatSemicolon();
  return new VariableDefinition(modifiers, type, names, values, this._makeSpan(start));
}
Parser.prototype.finishDefinition = function(start, modifiers, di) {
  switch (this._peek()) {
    case (2):

      var formals = this.formalParameterList();
      var inits = null, native_ = null;
      if (this._maybeEat((8))) {
        inits = this.initializers();
      }
      if (this._maybeEat((80))) {
        native_ = this.maybeStringLiteral();
        if ($eq$(native_)) native_ = "";
      }
      var body = this.functionBody(false);
      if ($eq$(di.get$name())) {
        di.set$name(di.get$type().get$name());
      }
      return new FunctionDefinition(modifiers, di.get$type(), di.get$name(), formals, inits, native_, body, this._makeSpan(start));

    case (20):

      this._eat((20));
      var value = this.expression();
      return this.finishField(start, modifiers, di.get$type(), di.get$name(), value);

    case (11):
    case (10):

      return this.finishField(start, modifiers, di.get$type(), di.get$name(), null);

    default:

      this._errorExpected("declaration");
      return null;

  }
}
Parser.prototype.declaration = function(includeOperators) {
  var start = this._peekToken.start;
  if (this._peekKind((74))) {
    return this.factoryConstructorDeclaration();
  }
  var modifiers = this._readModifiers();
  return this.finishDefinition(start, modifiers, this.declaredIdentifier(includeOperators));
}
Parser.prototype.factoryConstructorDeclaration = function() {
  var start = this._peekToken.start;
  var factoryToken = this._lang_next();
  var names = [this.identifier()];
  while (this._maybeEat((14))) {
    names.add(this.identifier());
  }
  if (this._peekKind((52))) {
    var tp = this.typeParameters();
    $globals.world.warning("type parameters on factories are no longer supported, place them on the class instead", this._makeSpan(tp.$index((0)).get$span().start));
  }
  var name = null;
  var type = null;
  if (this._maybeEat((14))) {
    name = this.identifier();
  }
  else {
    if (names.get$length() > (1)) {
      name = names.removeLast();
    }
    else {
      name = new Identifier("", names.$index((0)).get$span());
    }
  }
  if (names.get$length() > (1)) {
    this._error("unsupported qualified name for factory", names.$index((0)).get$span());
  }
  type = new NameTypeReference(false, names.$index((0)), null, names.$index((0)).get$span());
  var di = new DeclaredIdentifier(type, name, false, this._makeSpan(start));
  return this.finishDefinition(start, [factoryToken], di);
}
Parser.prototype.statement = function() {
  switch (this._peek()) {
    case (88):

      return this.breakStatement();

    case (93):

      return this.continueStatement();

    case (107):

      return this.returnStatement();

    case (111):

      return this.throwStatement();

    case (72):

      return this.assertStatement();

    case (116):

      return this.whileStatement();

    case (95):

      return this.doStatement();

    case (101):

      return this.forStatement();

    case (102):

      return this.ifStatement();

    case (109):

      return this.switchStatement();

    case (113):

      return this.tryStatement();

    case (6):

      return this.block();

    case (10):

      return this.emptyStatement();

    case (99):

      return this.declaration(false);

    case (114):

      return this.declaration(false);

    default:

      return this.finishExpressionAsStatement(this.expression());

  }
}
Parser.prototype.finishExpressionAsStatement = function(expr) {
  var start = expr.get$span().start;
  if (this._maybeEat((8))) {
    var label = this._makeLabel(expr);
    return new LabeledStatement(label, this.statement(), this._makeSpan(start));
  }
  if ((expr instanceof LambdaExpression)) {
    if (!(expr.get$func().body instanceof BlockStatement)) {
      this._eatSemicolon();
      expr.get$func().span = this._makeSpan(start);
    }
    return expr.get$func();
  }
  else if ((expr instanceof DeclaredIdentifier)) {
    var value = null;
    if (this._maybeEat((20))) {
      value = this.expression();
    }
    return this.finishField(start, null, expr.get$type(), expr.get$name(), value);
  }
  else if (this._isBin(expr, (20)) && ((expr.get$x() instanceof DeclaredIdentifier))) {
    var di = expr.get$x();
    return this.finishField(start, null, di.type, di.name, expr.get$y());
  }
  else if (this._isBin(expr, (52)) && this._maybeEat((11))) {
    var baseType = this._makeType(expr.get$x());
    var typeArgs = [this._makeType(expr.get$y())];
    var gt = this._finishTypeArguments(baseType, (0), typeArgs);
    var name = this.identifier();
    var value = null;
    if (this._maybeEat((20))) {
      value = this.expression();
    }
    return this.finishField(expr.get$span().start, null, gt, name, value);
  }
  else {
    this._eatSemicolon();
    return new ExpressionStatement(expr, this._makeSpan(expr.get$span().start));
  }
}
Parser.prototype.testCondition = function() {
  this._eatLeftParen();
  var ret = this.expression();
  this._eat((3));
  return ret;
}
Parser.prototype.block = function() {
  var start = this._peekToken.start;
  this._eat((6));
  var stmts = [];
  while (!this._maybeEat((7))) {
    stmts.add(this.statement());
    if (this._recover && !this._recoverTo((7), (10))) break;
  }
  this._recover = false;
  return new BlockStatement(stmts, this._makeSpan(start));
}
Parser.prototype.emptyStatement = function() {
  var start = this._peekToken.start;
  this._eat((10));
  return new EmptyStatement(this._makeSpan(start));
}
Parser.prototype.ifStatement = function() {
  var start = this._peekToken.start;
  this._eat((102));
  var test = this.testCondition();
  var trueBranch = this.statement();
  var falseBranch = null;
  if (this._maybeEat((96))) {
    falseBranch = this.statement();
  }
  return new IfStatement(test, trueBranch, falseBranch, this._makeSpan(start));
}
Parser.prototype.whileStatement = function() {
  var start = this._peekToken.start;
  this._eat((116));
  var test = this.testCondition();
  var body = this.statement();
  return new WhileStatement(test, body, this._makeSpan(start));
}
Parser.prototype.doStatement = function() {
  var start = this._peekToken.start;
  this._eat((95));
  var body = this.statement();
  this._eat((116));
  var test = this.testCondition();
  this._eatSemicolon();
  return new DoStatement(body, test, this._makeSpan(start));
}
Parser.prototype.forStatement = function() {
  var start = this._peekToken.start;
  this._eat((101));
  this._eatLeftParen();
  var init = this.forInitializerStatement(start);
  if ((init instanceof ForInStatement)) {
    return init;
  }
  var test = null;
  if (!this._maybeEat((10))) {
    test = this.expression();
    this._eatSemicolon();
  }
  var step = [];
  if (!this._maybeEat((3))) {
    step.add(this.expression());
    while (this._maybeEat((11))) {
      step.add(this.expression());
    }
    this._eat((3));
  }
  var body = this.statement();
  return new ForStatement(init, test, step, body, this._makeSpan(start));
}
Parser.prototype.forInitializerStatement = function(start) {
  if (this._maybeEat((10))) {
    return null;
  }
  else {
    var init = this.expression();
    if (this._peekKind((11)) && this._isBin(init, (52))) {
      this._eat((11));
      var baseType = this._makeType(init.get$x());
      var typeArgs = [this._makeType(init.get$y())];
      var gt = this._finishTypeArguments(baseType, (0), typeArgs);
      var name = this.identifier();
      init = new DeclaredIdentifier(gt, name, false, this._makeSpan(init.get$span().start));
    }
    if (this._maybeEat((103))) {
      return this._finishForIn(start, this._makeDeclaredIdentifier(init));
    }
    else {
      return this.finishExpressionAsStatement(init);
    }
  }
}
Parser.prototype._finishForIn = function(start, di) {
  var expr = this.expression();
  this._eat((3));
  var body = this.statement();
  return new ForInStatement(di, expr, body, this._makeSpan(start));
}
Parser.prototype.tryStatement = function() {
  var start = this._peekToken.start;
  this._eat((113));
  var body = this.block();
  var catches = [];
  while (this._peekKind((90))) {
    catches.add(this.catchNode());
  }
  var finallyBlock = null;
  if (this._maybeEat((100))) {
    finallyBlock = this.block();
  }
  return new TryStatement(body, catches, finallyBlock, this._makeSpan(start));
}
Parser.prototype.catchNode = function() {
  var start = this._peekToken.start;
  this._eat((90));
  this._eatLeftParen();
  var exc = this.declaredIdentifier(false);
  var trace = null;
  if (this._maybeEat((11))) {
    trace = this.declaredIdentifier(false);
  }
  this._eat((3));
  var body = this.block();
  return new CatchNode(exc, trace, body, this._makeSpan(start));
}
Parser.prototype.switchStatement = function() {
  var start = this._peekToken.start;
  this._eat((109));
  var test = this.testCondition();
  var cases = [];
  this._eat((6));
  while (!this._maybeEat((7))) {
    cases.add(this.caseNode());
  }
  return new SwitchStatement(test, cases, this._makeSpan(start));
}
Parser.prototype._peekCaseEnd = function() {
  var kind = this._peek();
  return $eq$(kind, (7)) || $eq$(kind, (89)) || $eq$(kind, (94));
}
Parser.prototype.caseNode = function() {
  var start = this._peekToken.start;
  var label = null;
  if (this._peekIdentifier()) {
    label = this.identifier();
    this._eat((8));
  }
  var cases = [];
  while (true) {
    if (this._maybeEat((89))) {
      cases.add(this.expression());
      this._eat((8));
    }
    else if (this._maybeEat((94))) {
      cases.add();
      this._eat((8));
    }
    else {
      break;
    }
  }
  if (cases.get$length() == (0)) {
    this._error("case or default");
  }
  var stmts = [];
  while (!this._peekCaseEnd()) {
    stmts.add(this.statement());
    if (this._recover && !this._recoverTo((7), (89), (94))) {
      break;
    }
  }
  return new CaseNode(label, cases, stmts, this._makeSpan(start));
}
Parser.prototype.returnStatement = function() {
  var start = this._peekToken.start;
  this._eat((107));
  var expr;
  if (this._maybeEat((10))) {
    expr = null;
  }
  else {
    expr = this.expression();
    this._eatSemicolon();
  }
  return new ReturnStatement(expr, this._makeSpan(start));
}
Parser.prototype.throwStatement = function() {
  var start = this._peekToken.start;
  this._eat((111));
  var expr;
  if (this._maybeEat((10))) {
    expr = null;
  }
  else {
    expr = this.expression();
    this._eatSemicolon();
  }
  return new ThrowStatement(expr, this._makeSpan(start));
}
Parser.prototype.assertStatement = function() {
  var start = this._peekToken.start;
  this._eat((72));
  this._eatLeftParen();
  var expr = this.expression();
  this._eat((3));
  this._eatSemicolon();
  return new AssertStatement(expr, this._makeSpan(start));
}
Parser.prototype.breakStatement = function() {
  var start = this._peekToken.start;
  this._eat((88));
  var name = null;
  if (this._peekIdentifier()) {
    name = this.identifier();
  }
  this._eatSemicolon();
  return new BreakStatement(name, this._makeSpan(start));
}
Parser.prototype.continueStatement = function() {
  var start = this._peekToken.start;
  this._eat((93));
  var name = null;
  if (this._peekIdentifier()) {
    name = this.identifier();
  }
  this._eatSemicolon();
  return new ContinueStatement(name, this._makeSpan(start));
}
Parser.prototype.expression = function() {
  return this.infixExpression((0));
}
Parser.prototype._makeType = function(expr) {
  if ((expr instanceof VarExpression)) {
    return new NameTypeReference(false, expr.get$name(), null, expr.get$span());
  }
  else if ((expr instanceof DotExpression)) {
    var type = this._makeType(expr.get$self());
    if (type.get$names() == null) {
      type.set$names([expr.get$name()]);
    }
    else {
      type.get$names().add(expr.get$name());
    }
    type.set$span(expr.get$span());
    return type;
  }
  else {
    this._error("expected type reference");
    return null;
  }
}
Parser.prototype.infixExpression = function(precedence) {
  return this.finishInfixExpression(this.unaryExpression(), precedence);
}
Parser.prototype._finishDeclaredId = function(type) {
  var name = this.identifier();
  return this.finishPostfixExpression(new DeclaredIdentifier(type, name, false, this._makeSpan(type.get$span().start)));
}
Parser.prototype._fixAsType = function(x) {
  if (this._maybeEat((53))) {
    var base = this._makeType(x.x);
    var typeParam = this._makeType(x.y);
    var type = new GenericTypeReference(base, [typeParam], (0), this._makeSpan(x.span.start));
    return this._finishDeclaredId(type);
  }
  else {
    var base = this._makeType(x.x);
    var paramBase = this._makeType(x.y);
    var firstParam = this.addTypeArguments(paramBase, (1));
    var type;
    if (firstParam.get$depth() <= (0)) {
      type = new GenericTypeReference(base, [firstParam], (0), this._makeSpan(x.span.start));
    }
    else if (this._maybeEat((11))) {
      type = this._finishTypeArguments(base, (0), [firstParam]);
    }
    else {
      this._eat((53));
      type = new GenericTypeReference(base, [firstParam], (0), this._makeSpan(x.span.start));
    }
    return this._finishDeclaredId(type);
  }
}
Parser.prototype.finishInfixExpression = function(x, precedence) {
  while (true) {
    var kind = this._peek();
    var prec = TokenKind.infixPrecedence(this._peek());
    if ($gte$(prec, precedence)) {
      if (kind == (52) || kind == (53)) {
        if (this._isBin(x, (52))) {
          return this._fixAsType(x);
        }
      }
      var op = this._lang_next();
      if (op.get$kind() == (104)) {
        var isTrue = !this._maybeEat((19));
        var typeRef = this.type((0));
        x = new IsExpression(isTrue, x, typeRef, this._makeSpan(x.span.start));
        continue;
      }
      var y = this.infixExpression($eq$(prec, (2)) ? prec : $add$(prec, (1)));
      if (op.get$kind() == (33)) {
        this._eat((8));
        var z = this.infixExpression(prec);
        x = new ConditionalExpression(x, y, z, this._makeSpan(x.span.start));
      }
      else {
        x = new BinaryExpression(op, x, y, this._makeSpan(x.span.start));
      }
    }
    else {
      break;
    }
  }
  return x;
}
Parser.prototype._isPrefixUnaryOperator = function(kind) {
  switch (kind) {
    case (42):
    case (43):
    case (19):
    case (18):
    case (16):
    case (17):

      return true;

    default:

      return false;

  }
}
Parser.prototype.unaryExpression = function() {
  var start = this._peekToken.start;
  if (this._isPrefixUnaryOperator(this._peek())) {
    var tok = this._lang_next();
    var expr = this.unaryExpression();
    return new UnaryExpression(tok, expr, this._makeSpan(start));
  }
  else if (this.get$enableAwait() && this._maybeEat((87))) {
    var expr = this.unaryExpression();
    return new AwaitExpression(expr, this._makeSpan(start));
  }
  return this.finishPostfixExpression(this.primary());
}
Parser.prototype.argument = function() {
  var start = this._peekToken.start;
  var expr;
  var label = null;
  if (this._maybeEat((15))) {
    label = new Identifier("...", this._makeSpan(start));
  }
  expr = this.expression();
  if ($eq$(label) && this._maybeEat((8))) {
    label = this._makeLabel(expr);
    expr = this.expression();
  }
  return new ArgumentNode(label, expr, this._makeSpan(start));
}
Parser.prototype.arguments = function() {
  var args = [];
  this._eatLeftParen();
  var saved = this._inhibitLambda;
  this._inhibitLambda = false;
  if (!this._maybeEat((3))) {
    do {
      args.add(this.argument());
    }
    while (this._maybeEat((11)))
    this._eat((3));
  }
  this._inhibitLambda = saved;
  return args;
}
Parser.prototype.finishPostfixExpression = function(expr) {
  switch (this._peek()) {
    case (2):

      return this.finishCallOrLambdaExpression(expr);

    case (4):

      this._eat((4));
      var index = this.expression();
      this._eat((5));
      return this.finishPostfixExpression(new IndexExpression(expr, index, this._makeSpan(expr.get$span().start)));

    case (14):

      this._eat((14));
      var name = this.identifier();
      var ret = new DotExpression(expr, name, this._makeSpan(expr.get$span().start));
      return this.finishPostfixExpression(ret);

    case (16):
    case (17):

      var tok = this._lang_next();
      return new PostfixExpression(expr, tok, this._makeSpan(expr.get$span().start));

    case (9):
    case (6):

      return expr;

    default:

      if (this._peekIdentifier()) {
        return this.finishPostfixExpression(new DeclaredIdentifier(this._makeType(expr), this.identifier(), false, this._makeSpan(expr.get$span().start)));
      }
      else {
        return expr;
      }

  }
}
Parser.prototype.finishCallOrLambdaExpression = function(expr) {
  if (this._atClosureParameters()) {
    var formals = this.formalParameterList();
    var body = this.functionBody(true);
    return this._makeFunction(expr, formals, body);
  }
  else {
    if ((expr instanceof DeclaredIdentifier)) {
      this._error("illegal target for call, did you mean to declare a function?", expr.get$span());
    }
    var args = this.arguments();
    return this.finishPostfixExpression(new CallExpression(expr, args, this._makeSpan(expr.get$span().start)));
  }
}
Parser.prototype._isBin = function(expr, kind) {
  return (expr instanceof BinaryExpression) && expr.get$op().kind == kind;
}
Parser.prototype._makeLiteral = function(value) {
  return new LiteralExpression(value, value.span);
}
Parser.prototype.primary = function() {
  var start = this._peekToken.start;
  switch (this._peek()) {
    case (110):

      this._eat((110));
      return new ThisExpression(this._makeSpan(start));

    case (108):

      this._eat((108));
      return new SuperExpression(this._makeSpan(start));

    case (92):

      this._eat((92));
      if (this._peekKind((4)) || this._peekKind((56))) {
        return this.finishListLiteral(start, true, null);
      }
      else if (this._peekKind((6))) {
        return this.finishMapLiteral(start, true, null, null);
      }
      else if (this._peekKind((52))) {
        return this.finishTypedLiteral(start, true);
      }
      else {
        return this.finishNewExpression(start, true);
      }

    case (105):

      this._eat((105));
      return this.finishNewExpression(start, false);

    case (2):

      return this._parenOrLambda();

    case (4):
    case (56):

      return this.finishListLiteral(start, false, null);

    case (6):

      return this.finishMapLiteral(start, false, null, null);

    case (106):

      this._eat((106));
      return this._makeLiteral(Value.fromNull(this._makeSpan(start)));

    case (112):

      this._eat((112));
      return this._makeLiteral(Value.fromBool(true, this._makeSpan(start)));

    case (98):

      this._eat((98));
      return this._makeLiteral(Value.fromBool(false, this._makeSpan(start)));

    case (61):

      var t = this._lang_next();
      return this._makeLiteral(Value.fromInt(t.get$value(), t.get$span()));

    case (60):

      var t = this._lang_next();
      return this._makeLiteral(Value.fromInt(Math.parseInt(t.get$text()), t.get$span()));

    case (62):

      var t = this._lang_next();
      return this._makeLiteral(Value.fromDouble(Math.parseDouble(t.get$text()), t.get$span()));

    case (58):

      var t = this._lang_next();
      return this._makeLiteral(Value.fromString(t.get$value(), t.get$span()));

    case (59):

      return this.stringInterpolation();

    case (52):

      return this.finishTypedLiteral(start, false);

    case (115):
    case (114):
    case (99):

      return this.declaredIdentifier(false);

    default:

      if (!this._peekIdentifier()) {
        this._errorExpected("expression");
      }
      return new VarExpression(this.identifier(), this._makeSpan(start));

  }
}
Parser.prototype.stringInterpolation = function() {
  var start = this._peekToken.start;
  var pieces = new Array();
  var startQuote = null, endQuote = null;
  while (this._peekKind((59))) {
    var token = this._lang_next();
    pieces.add(this._makeLiteral(Value.fromString(token.get$value(), token.get$span())));
    if (this._maybeEat((6))) {
      pieces.add(this.expression());
      this._eat((7));
    }
    else if (this._maybeEat((110))) {
      pieces.add(new ThisExpression(this._previousToken.get$span()));
    }
    else {
      var id = this.identifier();
      pieces.add(new VarExpression(id, id.get$span()));
    }
  }
  var tok = this._lang_next();
  if (tok.get$kind() != (58)) {
    this._errorExpected("interpolated string");
  }
  pieces.add(this._makeLiteral(Value.fromString(tok.get$value(), tok.get$span())));
  var span = this._makeSpan(start);
  return new StringInterpExpression(pieces, span);
}
Parser.prototype.maybeStringLiteral = function() {
  var kind = this._peek();
  if ($eq$(kind, (58))) {
    var t = this._lang_next();
    return t.get$value();
  }
  else if ($eq$(kind, (59))) {
    this._lang_next();
    this._errorExpected("string literal, but found interpolated string start");
  }
  return null;
}
Parser.prototype._parenOrLambda = function() {
  var start = this._peekToken.start;
  if (this._atClosureParameters()) {
    var formals = this.formalParameterList();
    var body = this.functionBody(true);
    var func = new FunctionDefinition(null, null, null, formals, null, null, body, this._makeSpan(start));
    return new LambdaExpression(func, func.get$span());
  }
  else {
    this._eatLeftParen();
    var saved = this._inhibitLambda;
    this._inhibitLambda = false;
    var expr = this.expression();
    this._eat((3));
    this._inhibitLambda = saved;
    return new ParenExpression(expr, this._makeSpan(start));
  }
}
Parser.prototype._atClosureParameters = function() {
  if (this._inhibitLambda) return false;
  var after = this._peekAfterCloseParen();
  return after.kind == (9) || after.kind == (6);
}
Parser.prototype._eatLeftParen = function() {
  this._eat((2));
  this._afterParensIndex++;
}
Parser.prototype._peekAfterCloseParen = function() {
  if (this._afterParensIndex < this._afterParens.get$length()) {
    return this._afterParens.$index(this._afterParensIndex);
  }
  this._afterParensIndex = (0);
  this._afterParens.clear();
  var tokens = [this._lang_next()];
  this._lookaheadAfterParens(tokens);
  var after = this._peekToken;
  tokens.add(after);
  this.tokenizer = new DivertedTokenSource(tokens, this, this.tokenizer);
  this._lang_next();
  return after;
}
Parser.prototype._lookaheadAfterParens = function(tokens) {
  var saved = this._afterParens.get$length();
  this._afterParens.add();
  while (true) {
    var token = this._lang_next();
    tokens.add(token);
    var kind = token.kind;
    if (kind == (3) || kind == (1)) {
      this._afterParens.$setindex(saved, this._peekToken);
      return;
    }
    else if (kind == (2)) {
      this._lookaheadAfterParens(tokens);
    }
  }
}
Parser.prototype._typeAsIdentifier = function(type) {
  if ($eq$(type.get$name().get$name(), "void")) {
    this._errorExpected(("identifer, but found \"" + type.get$name().get$name() + "\""));
  }
  return type.get$name();
}
Parser.prototype._specialIdentifier = function(includeOperators) {
  var start = this._peekToken.start;
  var name;
  switch (this._peek()) {
    case (15):

      this._eat((15));
      this._error("rest no longer supported", this._previousToken.get$span());
      name = this.identifier().get$name();
      break;

    case (110):

      this._eat((110));
      this._eat((14));
      name = ("this." + this.identifier().get$name());
      break;

    case (75):

      if (!includeOperators) return null;
      this._eat((75));
      if (this._peekIdentifier()) {
        name = ("get:" + this.identifier().get$name());
      }
      else {
        name = "get";
      }
      break;

    case (83):

      if (!includeOperators) return null;
      this._eat((83));
      if (this._peekIdentifier()) {
        name = ("set:" + this.identifier().get$name());
      }
      else {
        name = "set";
      }
      break;

    case (82):

      if (!includeOperators) return null;
      this._eat((82));
      var kind = this._peek();
      if ($eq$(kind, (81))) {
        name = ":negate";
        this._lang_next();
      }
      else {
        name = TokenKind.binaryMethodName(kind);
        if (name == null) {
          name = "operator";
        }
        else {
          this._lang_next();
        }
      }
      break;

    default:

      return null;

  }
  return new Identifier(name, this._makeSpan(start));
}
Parser.prototype.declaredIdentifier = function(includeOperators) {
  var start = this._peekToken.start;
  var myType = null;
  var name = this._specialIdentifier(includeOperators);
  var isFinal = false;
  if ($eq$(name)) {
    myType = this.type((0));
    name = this._specialIdentifier(includeOperators);
    if ($eq$(name)) {
      if (this._peekIdentifier()) {
        name = this.identifier();
      }
      else if ((myType instanceof NameTypeReference) && myType.get$names() == null) {
        name = this._typeAsIdentifier(myType);
        isFinal = myType.get$isFinal();
        myType = null;
      }
      else {
      }
    }
  }
  return new DeclaredIdentifier(myType, name, isFinal, this._makeSpan(start));
}
Parser.prototype.finishNewExpression = function(start, isConst) {
  var type = this.type((0));
  var name = null;
  if (this._maybeEat((14))) {
    name = this.identifier();
  }
  var args = this.arguments();
  return new NewExpression(isConst, type, name, args, this._makeSpan(start));
}
Parser.prototype.finishListLiteral = function(start, isConst, itemType) {
  if (this._maybeEat((56))) {
    return new ListExpression(isConst, itemType, [], this._makeSpan(start));
  }
  var values = [];
  this._eat((4));
  while (!this._maybeEat((5))) {
    values.add(this.expression());
    if (this._recover && !this._recoverTo((5), (11))) break;
    if (!this._maybeEat((11))) {
      this._eat((5));
      break;
    }
  }
  return new ListExpression(isConst, itemType, values, this._makeSpan(start));
}
Parser.prototype.finishMapLiteral = function(start, isConst, keyType, valueType) {
  var items = [];
  this._eat((6));
  while (!this._maybeEat((7))) {
    items.add(this.expression());
    this._eat((8));
    items.add(this.expression());
    if (this._recover && !this._recoverTo((7), (11))) break;
    if (!this._maybeEat((11))) {
      this._eat((7));
      break;
    }
  }
  return new MapExpression(isConst, keyType, valueType, items, this._makeSpan(start));
}
Parser.prototype.finishTypedLiteral = function(start, isConst) {
  var span = this._makeSpan(start);
  var typeToBeNamedLater = new NameTypeReference(false, null, null, span);
  var genericType = this.addTypeArguments(typeToBeNamedLater, (0));
  var typeArgs = genericType.get$typeArguments();
  if (this._peekKind((4)) || this._peekKind((56))) {
    if (typeArgs.get$length() != (1)) {
      $globals.world.error("exactly one type argument expected for list", genericType.get$span());
    }
    return this.finishListLiteral(start, isConst, typeArgs.$index((0)));
  }
  else if (this._peekKind((6))) {
    var keyType, valueType;
    if (typeArgs.get$length() == (1)) {
      keyType = null;
      valueType = typeArgs.$index((0));
    }
    else if (typeArgs.get$length() == (2)) {
      keyType = typeArgs.$index((0));
      $globals.world.warning("a map literal takes one type argument specifying the value type", keyType.get$span());
      valueType = typeArgs.$index((1));
    }
    return this.finishMapLiteral(start, isConst, keyType, valueType);
  }
  else {
    this._errorExpected("array or map literal");
  }
}
Parser.prototype._readModifiers = function() {
  var modifiers = null;
  while (true) {
    switch (this._peek()) {
      case (85):
      case (99):
      case (92):
      case (71):
      case (74):

        if ($eq$(modifiers)) modifiers = [];
        modifiers.add(this._lang_next());
        break;

      default:

        return modifiers;

    }
  }
  return null;
}
Parser.prototype.typeParameter = function() {
  var start = this._peekToken.start;
  var name = this.identifier();
  var myType = null;
  if (this._maybeEat((97))) {
    myType = this.type((1));
  }
  var tp = new TypeParameter(name, myType, this._makeSpan(start));
  return new ParameterType(name.get$name(), tp);
}
Parser.prototype.get$typeParameter = function() {
  return this.typeParameter.bind(this);
}
Parser.prototype.typeParameters = function() {
  this._eat((52));
  var closed = false;
  var ret = [];
  do {
    var tp = this.typeParameter();
    ret.add(tp);
    if ((tp.get$typeParameter().get$extendsType() instanceof GenericTypeReference) && tp.get$typeParameter().get$extendsType().get$dynamic().get$depth() == (0)) {
      closed = true;
      break;
    }
  }
  while (this._maybeEat((11)))
  if (!closed) {
    this._eat((53));
  }
  return ret;
}
Parser.prototype.get$typeParameters = function() {
  return this.typeParameters.bind(this);
}
Parser.prototype._eatClosingAngle = function(depth) {
  if (this._maybeEat((53))) {
    return depth;
  }
  else if (depth > (0) && this._maybeEat((40))) {
    return depth - (1);
  }
  else if (depth > (1) && this._maybeEat((41))) {
    return depth - (2);
  }
  else {
    this._errorExpected(">");
    return depth;
  }
}
Parser.prototype.addTypeArguments = function(baseType, depth) {
  this._eat((52));
  return this._finishTypeArguments(baseType, depth, []);
}
Parser.prototype._finishTypeArguments = function(baseType, depth, types) {
  var delta = (-1);
  do {
    var myType = this.type(depth + (1));
    types.add(myType);
    if ((myType instanceof GenericTypeReference) && myType.get$depth() <= depth) {
      delta = depth - myType.get$depth();
      break;
    }
  }
  while (this._maybeEat((11)))
  if ($gte$(delta, (0))) {
    depth = $sub$(depth, delta);
  }
  else {
    depth = this._eatClosingAngle(depth);
  }
  var span = this._makeSpan(baseType.span.start);
  return new GenericTypeReference(baseType, types, depth, span);
}
Parser.prototype.typeList = function() {
  var types = [];
  do {
    types.add(this.type((0)));
  }
  while (this._maybeEat((11)))
  return types;
}
Parser.prototype.nameTypeReference = function() {
  var start = this._peekToken.start;
  var name;
  var names = null;
  var typeArgs = null;
  var isFinal = false;
  switch (this._peek()) {
    case (115):

      return new SimpleTypeReference($globals.world.voidType, this._lang_next().get$span());

    case (114):

      return new SimpleTypeReference($globals.world.varType, this._lang_next().get$span());

    case (99):

      this._eat((99));
      isFinal = true;
      name = this.identifier();
      break;

    default:

      name = this.identifier();
      break;

  }
  while (this._maybeEat((14))) {
    if ($eq$(names)) names = [];
    names.add(this.identifier());
  }
  return new NameTypeReference(isFinal, name, names, this._makeSpan(start));
}
Parser.prototype.type = function(depth) {
  var typeRef = this.nameTypeReference();
  if (this._peekKind((52))) {
    return this.addTypeArguments(typeRef, depth);
  }
  else {
    return typeRef;
  }
}
Parser.prototype.type.$optional = ['depth', '(0)']
Parser.prototype.get$type = function() {
  return this.type.bind(this);
}
Parser.prototype.formalParameter = function(inOptionalBlock) {
  var start = this._peekToken.start;
  var isThis = false;
  var isRest = false;
  var di = this.declaredIdentifier(false);
  var type = di.get$type();
  var name = di.get$name();
  if ($eq$(name)) {
    this._error("Formal parameter invalid", this._makeSpan(start));
  }
  var value = null;
  if (this._maybeEat((20))) {
    if (!inOptionalBlock) {
      this._error("default values only allowed inside [optional] section");
    }
    value = this.expression();
  }
  else if (this._peekKind((2))) {
    var formals = this.formalParameterList();
    var func = new FunctionDefinition(null, type, name, formals, null, null, null, this._makeSpan(start));
    type = new FunctionTypeReference(false, func, func.get$span());
  }
  if (inOptionalBlock && $eq$(value)) {
    value = this._makeLiteral(Value.fromNull(this._makeSpan(start)));
  }
  return new FormalNode(isThis, isRest, type, name, value, this._makeSpan(start));
}
Parser.prototype.formalParameterList = function() {
  this._eatLeftParen();
  var formals = [];
  var inOptionalBlock = false;
  if (!this._maybeEat((3))) {
    if (this._maybeEat((4))) {
      inOptionalBlock = true;
    }
    formals.add(this.formalParameter(inOptionalBlock));
    while (this._maybeEat((11))) {
      if (this._maybeEat((4))) {
        if (inOptionalBlock) {
          this._error("already inside an optional block", this._previousToken.get$span());
        }
        inOptionalBlock = true;
      }
      formals.add(this.formalParameter(inOptionalBlock));
    }
    if (inOptionalBlock) {
      this._eat((5));
    }
    this._eat((3));
  }
  return formals;
}
Parser.prototype.identifierForType = function() {
  var $0;
  var tok = this._lang_next();
  if (!this._isIdentifier(tok.get$kind())) {
    this._error(("expected identifier, but found " + tok), tok.get$span());
  }
  if ((($0 = tok.get$kind()) == null ? null != ((70)) : $0 !== (70)) && tok.get$kind() != (80)) {
    this._error(("" + tok + " may not be used as a type name"), tok.get$span());
  }
  return new Identifier(tok.get$text(), this._makeSpan(tok.get$start()));
}
Parser.prototype.identifier = function() {
  var tok = this._lang_next();
  if (!this._isIdentifier(tok.get$kind())) {
    this._error(("expected identifier, but found " + tok), tok.get$span());
  }
  return new Identifier(tok.get$text(), this._makeSpan(tok.get$start()));
}
Parser.prototype._makeFunction = function(expr, formals, body) {
  var name, type;
  if ((expr instanceof VarExpression)) {
    name = expr.get$name();
    type = null;
  }
  else if ((expr instanceof DeclaredIdentifier)) {
    name = expr.get$name();
    type = expr.get$type();
    if ($eq$(name)) {
      this._error("expected name and type", expr.get$span());
    }
  }
  else {
    this._error("bad function body", expr.get$span());
  }
  var span = new SourceSpan(expr.get$span().file, expr.get$span().start, body.get$span().end);
  var func = new FunctionDefinition(null, type, name, formals, null, null, body, span);
  return new LambdaExpression(func, func.get$span());
}
Parser.prototype._makeDeclaredIdentifier = function(e) {
  if ((e instanceof VarExpression)) {
    return new DeclaredIdentifier(null, e.get$name(), false, e.get$span());
  }
  else if ((e instanceof DeclaredIdentifier)) {
    return e;
  }
  else {
    this._error("expected declared identifier");
    return new DeclaredIdentifier(null, null, false, e.get$span());
  }
}
Parser.prototype._makeLabel = function(expr) {
  if ((expr instanceof VarExpression)) {
    return expr.get$name();
  }
  else {
    this._errorExpected("label");
    return null;
  }
}
// ********** Code for IncompleteSourceException **************
function IncompleteSourceException(token) {
  this.token = token;
}
IncompleteSourceException.prototype.toString = function() {
  if (this.token.get$span() == null) return ("Unexpected " + this.token);
  return this.token.get$span().toMessageString(("Unexpected " + this.token));
}
IncompleteSourceException.prototype.toString$0 = IncompleteSourceException.prototype.toString;
// ********** Code for DivertedTokenSource **************
function DivertedTokenSource(tokens, parser, previousTokenizer) {
  this.parser = parser;
  this._lang_pos = (0);
  this.tokens = tokens;
  this.previousTokenizer = previousTokenizer;
}
DivertedTokenSource.prototype.next = function() {
  var token = this.tokens.$index(this._lang_pos);
  ++this._lang_pos;
  if (this._lang_pos == this.tokens.get$length()) {
    this.parser.tokenizer = this.previousTokenizer;
  }
  return token;
}
// ********** Code for Node **************
function Node(span) {
  this.span = span;
}
Node.prototype.get$span = function() { return this.span; };
Node.prototype.set$span = function(value) { return this.span = value; };
// ********** Code for Statement **************
$inherits(Statement, Node);
function Statement(span) {
  Node.call(this, span);
}
// ********** Code for Definition **************
$inherits(Definition, Statement);
function Definition(span) {
  Statement.call(this, span);
}
Definition.prototype.get$typeParameters = function() {
  return null;
}
Definition.prototype.get$nativeType = function() {
  return null;
}
// ********** Code for Expression **************
$inherits(Expression, Node);
function Expression(span) {
  Node.call(this, span);
}
// ********** Code for TypeReference **************
$inherits(TypeReference, Node);
function TypeReference(span) {
  Node.call(this, span);
}
// ********** Code for DirectiveDefinition **************
$inherits(DirectiveDefinition, Definition);
function DirectiveDefinition(name, arguments, span) {
  this.arguments = arguments;
  this.name = name;
  Definition.call(this, span);
}
DirectiveDefinition.prototype.get$name = function() { return this.name; };
DirectiveDefinition.prototype.set$name = function(value) { return this.name = value; };
DirectiveDefinition.prototype.visit = function(visitor) {
  return visitor.visitDirectiveDefinition(this);
}
// ********** Code for TypeDefinition **************
$inherits(TypeDefinition, Definition);
function TypeDefinition(isClass, name, typeParameters, extendsTypes, implementsTypes, nativeType, defaultType, body, span) {
  this.extendsTypes = extendsTypes;
  this.isClass = isClass;
  this.name = name;
  this.body = body;
  this.typeParameters = typeParameters;
  this.nativeType = nativeType;
  this.implementsTypes = implementsTypes;
  this.defaultType = defaultType;
  Definition.call(this, span);
}
TypeDefinition.prototype.get$isClass = function() { return this.isClass; };
TypeDefinition.prototype.get$name = function() { return this.name; };
TypeDefinition.prototype.set$name = function(value) { return this.name = value; };
TypeDefinition.prototype.get$typeParameters = function() { return this.typeParameters; };
TypeDefinition.prototype.get$nativeType = function() { return this.nativeType; };
TypeDefinition.prototype.get$body = function() { return this.body; };
TypeDefinition.prototype.visit = function(visitor) {
  return visitor.visitTypeDefinition(this);
}
// ********** Code for FunctionTypeDefinition **************
$inherits(FunctionTypeDefinition, Definition);
function FunctionTypeDefinition(func, typeParameters, span) {
  this.typeParameters = typeParameters;
  this.func = func;
  Definition.call(this, span);
}
FunctionTypeDefinition.prototype.get$func = function() { return this.func; };
FunctionTypeDefinition.prototype.get$typeParameters = function() { return this.typeParameters; };
FunctionTypeDefinition.prototype.visit = function(visitor) {
  return visitor.visitFunctionTypeDefinition(this);
}
// ********** Code for VariableDefinition **************
$inherits(VariableDefinition, Definition);
function VariableDefinition(modifiers, type, names, values, span) {
  this.modifiers = modifiers;
  this.type = type;
  this.names = names;
  this.values = values;
  Definition.call(this, span);
}
VariableDefinition.prototype.get$type = function() { return this.type; };
VariableDefinition.prototype.get$names = function() { return this.names; };
VariableDefinition.prototype.set$names = function(value) { return this.names = value; };
VariableDefinition.prototype.visit = function(visitor) {
  return visitor.visitVariableDefinition(this);
}
// ********** Code for FunctionDefinition **************
$inherits(FunctionDefinition, Definition);
function FunctionDefinition(modifiers, returnType, name, formals, initializers, nativeBody, body, span) {
  this.modifiers = modifiers;
  this.name = name;
  this.initializers = initializers;
  this.body = body;
  this.returnType = returnType;
  this.formals = formals;
  this.nativeBody = nativeBody;
  Definition.call(this, span);
}
FunctionDefinition.prototype.get$returnType = function() { return this.returnType; };
FunctionDefinition.prototype.set$returnType = function(value) { return this.returnType = value; };
FunctionDefinition.prototype.get$name = function() { return this.name; };
FunctionDefinition.prototype.set$name = function(value) { return this.name = value; };
FunctionDefinition.prototype.get$initializers = function() { return this.initializers; };
FunctionDefinition.prototype.get$body = function() { return this.body; };
FunctionDefinition.prototype.visit = function(visitor) {
  return visitor.visitFunctionDefinition(this);
}
// ********** Code for ReturnStatement **************
$inherits(ReturnStatement, Statement);
function ReturnStatement(value, span) {
  this.value = value;
  Statement.call(this, span);
}
ReturnStatement.prototype.get$value = function() { return this.value; };
ReturnStatement.prototype.set$value = function(value) { return this.value = value; };
ReturnStatement.prototype.visit = function(visitor) {
  return visitor.visitReturnStatement(this);
}
// ********** Code for ThrowStatement **************
$inherits(ThrowStatement, Statement);
function ThrowStatement(value, span) {
  this.value = value;
  Statement.call(this, span);
}
ThrowStatement.prototype.get$value = function() { return this.value; };
ThrowStatement.prototype.set$value = function(value) { return this.value = value; };
ThrowStatement.prototype.visit = function(visitor) {
  return visitor.visitThrowStatement(this);
}
// ********** Code for AssertStatement **************
$inherits(AssertStatement, Statement);
function AssertStatement(test, span) {
  this.test = test;
  Statement.call(this, span);
}
AssertStatement.prototype.visit = function(visitor) {
  return visitor.visitAssertStatement(this);
}
// ********** Code for BreakStatement **************
$inherits(BreakStatement, Statement);
function BreakStatement(label, span) {
  this.label = label;
  Statement.call(this, span);
}
BreakStatement.prototype.get$label = function() { return this.label; };
BreakStatement.prototype.visit = function(visitor) {
  return visitor.visitBreakStatement(this);
}
// ********** Code for ContinueStatement **************
$inherits(ContinueStatement, Statement);
function ContinueStatement(label, span) {
  this.label = label;
  Statement.call(this, span);
}
ContinueStatement.prototype.get$label = function() { return this.label; };
ContinueStatement.prototype.visit = function(visitor) {
  return visitor.visitContinueStatement(this);
}
// ********** Code for IfStatement **************
$inherits(IfStatement, Statement);
function IfStatement(test, trueBranch, falseBranch, span) {
  this.test = test;
  this.falseBranch = falseBranch;
  this.trueBranch = trueBranch;
  Statement.call(this, span);
}
IfStatement.prototype.visit = function(visitor) {
  return visitor.visitIfStatement(this);
}
// ********** Code for WhileStatement **************
$inherits(WhileStatement, Statement);
function WhileStatement(test, body, span) {
  this.body = body;
  this.test = test;
  Statement.call(this, span);
}
WhileStatement.prototype.get$body = function() { return this.body; };
WhileStatement.prototype.visit = function(visitor) {
  return visitor.visitWhileStatement(this);
}
// ********** Code for DoStatement **************
$inherits(DoStatement, Statement);
function DoStatement(body, test, span) {
  this.body = body;
  this.test = test;
  Statement.call(this, span);
}
DoStatement.prototype.get$body = function() { return this.body; };
DoStatement.prototype.visit = function(visitor) {
  return visitor.visitDoStatement(this);
}
// ********** Code for ForStatement **************
$inherits(ForStatement, Statement);
function ForStatement(init, test, step, body, span) {
  this.body = body;
  this.test = test;
  this.step = step;
  this.init = init;
  Statement.call(this, span);
}
ForStatement.prototype.get$body = function() { return this.body; };
ForStatement.prototype.visit = function(visitor) {
  return visitor.visitForStatement(this);
}
// ********** Code for ForInStatement **************
$inherits(ForInStatement, Statement);
function ForInStatement(item, list, body, span) {
  this.body = body;
  this.item = item;
  this.list = list;
  Statement.call(this, span);
}
ForInStatement.prototype.get$body = function() { return this.body; };
ForInStatement.prototype.visit = function(visitor) {
  return visitor.visitForInStatement(this);
}
// ********** Code for TryStatement **************
$inherits(TryStatement, Statement);
function TryStatement(body, catches, finallyBlock, span) {
  this.body = body;
  this.finallyBlock = finallyBlock;
  this.catches = catches;
  Statement.call(this, span);
}
TryStatement.prototype.get$body = function() { return this.body; };
TryStatement.prototype.visit = function(visitor) {
  return visitor.visitTryStatement(this);
}
// ********** Code for SwitchStatement **************
$inherits(SwitchStatement, Statement);
function SwitchStatement(test, cases, span) {
  this.test = test;
  this.cases = cases;
  Statement.call(this, span);
}
SwitchStatement.prototype.get$cases = function() { return this.cases; };
SwitchStatement.prototype.visit = function(visitor) {
  return visitor.visitSwitchStatement(this);
}
// ********** Code for BlockStatement **************
$inherits(BlockStatement, Statement);
function BlockStatement(body, span) {
  this.body = body;
  Statement.call(this, span);
}
BlockStatement.prototype.get$body = function() { return this.body; };
BlockStatement.prototype.visit = function(visitor) {
  return visitor.visitBlockStatement(this);
}
// ********** Code for LabeledStatement **************
$inherits(LabeledStatement, Statement);
function LabeledStatement(name, body, span) {
  this.body = body;
  this.name = name;
  Statement.call(this, span);
}
LabeledStatement.prototype.get$name = function() { return this.name; };
LabeledStatement.prototype.set$name = function(value) { return this.name = value; };
LabeledStatement.prototype.get$body = function() { return this.body; };
LabeledStatement.prototype.visit = function(visitor) {
  return visitor.visitLabeledStatement(this);
}
// ********** Code for ExpressionStatement **************
$inherits(ExpressionStatement, Statement);
function ExpressionStatement(body, span) {
  this.body = body;
  Statement.call(this, span);
}
ExpressionStatement.prototype.get$body = function() { return this.body; };
ExpressionStatement.prototype.visit = function(visitor) {
  return visitor.visitExpressionStatement(this);
}
// ********** Code for EmptyStatement **************
$inherits(EmptyStatement, Statement);
function EmptyStatement(span) {
  Statement.call(this, span);
}
EmptyStatement.prototype.visit = function(visitor) {
  return visitor.visitEmptyStatement(this);
}
// ********** Code for DietStatement **************
$inherits(DietStatement, Statement);
function DietStatement(span) {
  Statement.call(this, span);
}
DietStatement.prototype.visit = function(visitor) {
  return visitor.visitDietStatement(this);
}
// ********** Code for LambdaExpression **************
$inherits(LambdaExpression, Expression);
function LambdaExpression(func, span) {
  this.func = func;
  Expression.call(this, span);
}
LambdaExpression.prototype.get$func = function() { return this.func; };
LambdaExpression.prototype.visit = function(visitor) {
  return visitor.visitLambdaExpression(this);
}
// ********** Code for CallExpression **************
$inherits(CallExpression, Expression);
function CallExpression(target, arguments, span) {
  this.target = target;
  this.arguments = arguments;
  Expression.call(this, span);
}
CallExpression.prototype.visit = function(visitor) {
  return visitor.visitCallExpression$1(this);
}
// ********** Code for IndexExpression **************
$inherits(IndexExpression, Expression);
function IndexExpression(target, index, span) {
  this.target = target;
  this.index = index;
  Expression.call(this, span);
}
IndexExpression.prototype.visit = function(visitor) {
  return visitor.visitIndexExpression(this);
}
// ********** Code for BinaryExpression **************
$inherits(BinaryExpression, Expression);
function BinaryExpression(op, x, y, span) {
  this.y = y;
  this.x = x;
  this.op = op;
  Expression.call(this, span);
}
BinaryExpression.prototype.get$op = function() { return this.op; };
BinaryExpression.prototype.get$x = function() { return this.x; };
BinaryExpression.prototype.get$y = function() { return this.y; };
BinaryExpression.prototype.visit = function(visitor) {
  return visitor.visitBinaryExpression$1(this);
}
// ********** Code for UnaryExpression **************
$inherits(UnaryExpression, Expression);
function UnaryExpression(op, self, span) {
  this.self = self;
  this.op = op;
  Expression.call(this, span);
}
UnaryExpression.prototype.get$op = function() { return this.op; };
UnaryExpression.prototype.get$self = function() { return this.self; };
UnaryExpression.prototype.visit = function(visitor) {
  return visitor.visitUnaryExpression(this);
}
// ********** Code for PostfixExpression **************
$inherits(PostfixExpression, Expression);
function PostfixExpression(body, op, span) {
  this.body = body;
  this.op = op;
  Expression.call(this, span);
}
PostfixExpression.prototype.get$body = function() { return this.body; };
PostfixExpression.prototype.get$op = function() { return this.op; };
PostfixExpression.prototype.visit = function(visitor) {
  return visitor.visitPostfixExpression$1(this);
}
// ********** Code for NewExpression **************
$inherits(NewExpression, Expression);
function NewExpression(isConst, type, name, arguments, span) {
  this.arguments = arguments;
  this.name = name;
  this.type = type;
  this.isConst = isConst;
  Expression.call(this, span);
}
NewExpression.prototype.get$isConst = function() { return this.isConst; };
NewExpression.prototype.get$type = function() { return this.type; };
NewExpression.prototype.get$name = function() { return this.name; };
NewExpression.prototype.set$name = function(value) { return this.name = value; };
NewExpression.prototype.visit = function(visitor) {
  return visitor.visitNewExpression(this);
}
// ********** Code for ListExpression **************
$inherits(ListExpression, Expression);
function ListExpression(isConst, itemType, values, span) {
  this.itemType = itemType;
  this.isConst = isConst;
  this.values = values;
  Expression.call(this, span);
}
ListExpression.prototype.get$isConst = function() { return this.isConst; };
ListExpression.prototype.visit = function(visitor) {
  return visitor.visitListExpression(this);
}
// ********** Code for MapExpression **************
$inherits(MapExpression, Expression);
function MapExpression(isConst, keyType, valueType, items, span) {
  this.keyType = keyType;
  this.valueType = valueType;
  this.items = items;
  this.isConst = isConst;
  Expression.call(this, span);
}
MapExpression.prototype.get$isConst = function() { return this.isConst; };
MapExpression.prototype.visit = function(visitor) {
  return visitor.visitMapExpression(this);
}
// ********** Code for ConditionalExpression **************
$inherits(ConditionalExpression, Expression);
function ConditionalExpression(test, trueBranch, falseBranch, span) {
  this.test = test;
  this.falseBranch = falseBranch;
  this.trueBranch = trueBranch;
  Expression.call(this, span);
}
ConditionalExpression.prototype.visit = function(visitor) {
  return visitor.visitConditionalExpression(this);
}
// ********** Code for IsExpression **************
$inherits(IsExpression, Expression);
function IsExpression(isTrue, x, type, span) {
  this.isTrue = isTrue;
  this.x = x;
  this.type = type;
  Expression.call(this, span);
}
IsExpression.prototype.get$x = function() { return this.x; };
IsExpression.prototype.get$type = function() { return this.type; };
IsExpression.prototype.visit = function(visitor) {
  return visitor.visitIsExpression(this);
}
// ********** Code for ParenExpression **************
$inherits(ParenExpression, Expression);
function ParenExpression(body, span) {
  this.body = body;
  Expression.call(this, span);
}
ParenExpression.prototype.get$body = function() { return this.body; };
ParenExpression.prototype.visit = function(visitor) {
  return visitor.visitParenExpression(this);
}
// ********** Code for AwaitExpression **************
$inherits(AwaitExpression, Expression);
function AwaitExpression(body, span) {
  this.body = body;
  Expression.call(this, span);
}
AwaitExpression.prototype.get$body = function() { return this.body; };
AwaitExpression.prototype.visit = function(visitor) {
  return visitor.visitAwaitExpression(this);
}
// ********** Code for DotExpression **************
$inherits(DotExpression, Expression);
function DotExpression(self, name, span) {
  this.self = self;
  this.name = name;
  Expression.call(this, span);
}
DotExpression.prototype.get$self = function() { return this.self; };
DotExpression.prototype.get$name = function() { return this.name; };
DotExpression.prototype.set$name = function(value) { return this.name = value; };
DotExpression.prototype.visit = function(visitor) {
  return visitor.visitDotExpression(this);
}
// ********** Code for VarExpression **************
$inherits(VarExpression, Expression);
function VarExpression(name, span) {
  this.name = name;
  Expression.call(this, span);
}
VarExpression.prototype.get$name = function() { return this.name; };
VarExpression.prototype.set$name = function(value) { return this.name = value; };
VarExpression.prototype.visit = function(visitor) {
  return visitor.visitVarExpression(this);
}
// ********** Code for ThisExpression **************
$inherits(ThisExpression, Expression);
function ThisExpression(span) {
  Expression.call(this, span);
}
ThisExpression.prototype.visit = function(visitor) {
  return visitor.visitThisExpression(this);
}
// ********** Code for SuperExpression **************
$inherits(SuperExpression, Expression);
function SuperExpression(span) {
  Expression.call(this, span);
}
SuperExpression.prototype.visit = function(visitor) {
  return visitor.visitSuperExpression(this);
}
// ********** Code for LiteralExpression **************
$inherits(LiteralExpression, Expression);
function LiteralExpression(value, span) {
  this.value = value;
  Expression.call(this, span);
}
LiteralExpression.prototype.get$value = function() { return this.value; };
LiteralExpression.prototype.set$value = function(value) { return this.value = value; };
LiteralExpression.prototype.visit = function(visitor) {
  return visitor.visitLiteralExpression(this);
}
// ********** Code for StringInterpExpression **************
$inherits(StringInterpExpression, Expression);
function StringInterpExpression(pieces, span) {
  this.pieces = pieces;
  Expression.call(this, span);
}
StringInterpExpression.prototype.visit = function(visitor) {
  return visitor.visitStringInterpExpression(this);
}
// ********** Code for SimpleTypeReference **************
$inherits(SimpleTypeReference, TypeReference);
function SimpleTypeReference(type, span) {
  this.type = type;
  TypeReference.call(this, span);
}
SimpleTypeReference.prototype.get$type = function() { return this.type; };
SimpleTypeReference.prototype.visit = function(visitor) {
  return visitor.visitSimpleTypeReference(this);
}
// ********** Code for NameTypeReference **************
$inherits(NameTypeReference, TypeReference);
function NameTypeReference(isFinal, name, names, span) {
  this.name = name;
  this.names = names;
  this.isFinal = isFinal;
  TypeReference.call(this, span);
}
NameTypeReference.prototype.get$isFinal = function() { return this.isFinal; };
NameTypeReference.prototype.get$name = function() { return this.name; };
NameTypeReference.prototype.set$name = function(value) { return this.name = value; };
NameTypeReference.prototype.get$names = function() { return this.names; };
NameTypeReference.prototype.set$names = function(value) { return this.names = value; };
NameTypeReference.prototype.visit = function(visitor) {
  return visitor.visitNameTypeReference(this);
}
// ********** Code for GenericTypeReference **************
$inherits(GenericTypeReference, TypeReference);
function GenericTypeReference(baseType, typeArguments, depth, span) {
  this.depth = depth;
  this.baseType = baseType;
  this.typeArguments = typeArguments;
  TypeReference.call(this, span);
}
GenericTypeReference.prototype.get$baseType = function() { return this.baseType; };
GenericTypeReference.prototype.get$typeArguments = function() { return this.typeArguments; };
GenericTypeReference.prototype.get$depth = function() { return this.depth; };
GenericTypeReference.prototype.visit = function(visitor) {
  return visitor.visitGenericTypeReference(this);
}
// ********** Code for FunctionTypeReference **************
$inherits(FunctionTypeReference, TypeReference);
function FunctionTypeReference(isFinal, func, span) {
  this.func = func;
  this.isFinal = isFinal;
  TypeReference.call(this, span);
}
FunctionTypeReference.prototype.get$isFinal = function() { return this.isFinal; };
FunctionTypeReference.prototype.get$func = function() { return this.func; };
FunctionTypeReference.prototype.visit = function(visitor) {
  return visitor.visitFunctionTypeReference(this);
}
// ********** Code for DefaultTypeReference **************
$inherits(DefaultTypeReference, TypeReference);
function DefaultTypeReference(oldFactory, baseType, typeParameters, span) {
  this.typeParameters = typeParameters;
  this.oldFactory = oldFactory;
  this.baseType = baseType;
  TypeReference.call(this, span);
}
DefaultTypeReference.prototype.get$baseType = function() { return this.baseType; };
DefaultTypeReference.prototype.get$typeParameters = function() { return this.typeParameters; };
DefaultTypeReference.prototype.visit = function(visitor) {
  return visitor.visitDefaultTypeReference(this);
}
// ********** Code for ArgumentNode **************
$inherits(ArgumentNode, Node);
function ArgumentNode(label, value, span) {
  this.label = label;
  this.value = value;
  Node.call(this, span);
}
ArgumentNode.prototype.get$label = function() { return this.label; };
ArgumentNode.prototype.get$value = function() { return this.value; };
ArgumentNode.prototype.set$value = function(value) { return this.value = value; };
ArgumentNode.prototype.visit = function(visitor) {
  return visitor.visitArgumentNode(this);
}
// ********** Code for FormalNode **************
$inherits(FormalNode, Node);
function FormalNode(isThis, isRest, type, name, value, span) {
  this.name = name;
  this.isThis = isThis;
  this.type = type;
  this.isRest = isRest;
  this.value = value;
  Node.call(this, span);
}
FormalNode.prototype.get$type = function() { return this.type; };
FormalNode.prototype.get$name = function() { return this.name; };
FormalNode.prototype.set$name = function(value) { return this.name = value; };
FormalNode.prototype.get$value = function() { return this.value; };
FormalNode.prototype.set$value = function(value) { return this.value = value; };
FormalNode.prototype.visit = function(visitor) {
  return visitor.visitFormalNode(this);
}
// ********** Code for CatchNode **************
$inherits(CatchNode, Node);
function CatchNode(exception, trace, body, span) {
  this.body = body;
  this.exception = exception;
  this.trace = trace;
  Node.call(this, span);
}
CatchNode.prototype.get$exception = function() { return this.exception; };
CatchNode.prototype.get$trace = function() { return this.trace; };
CatchNode.prototype.get$body = function() { return this.body; };
CatchNode.prototype.visit = function(visitor) {
  return visitor.visitCatchNode(this);
}
// ********** Code for CaseNode **************
$inherits(CaseNode, Node);
function CaseNode(label, cases, statements, span) {
  this.label = label;
  this.statements = statements;
  this.cases = cases;
  Node.call(this, span);
}
CaseNode.prototype.get$label = function() { return this.label; };
CaseNode.prototype.get$cases = function() { return this.cases; };
CaseNode.prototype.get$statements = function() { return this.statements; };
CaseNode.prototype.visit = function(visitor) {
  return visitor.visitCaseNode(this);
}
// ********** Code for TypeParameter **************
$inherits(TypeParameter, Node);
function TypeParameter(name, extendsType, span) {
  this.extendsType = extendsType;
  this.name = name;
  Node.call(this, span);
}
TypeParameter.prototype.get$name = function() { return this.name; };
TypeParameter.prototype.set$name = function(value) { return this.name = value; };
TypeParameter.prototype.get$extendsType = function() { return this.extendsType; };
TypeParameter.prototype.visit = function(visitor) {
  return visitor.visitTypeParameter(this);
}
// ********** Code for Identifier **************
$inherits(Identifier, Node);
function Identifier(name, span) {
  this.name = name;
  Node.call(this, span);
}
Identifier.prototype.get$name = function() { return this.name; };
Identifier.prototype.set$name = function(value) { return this.name = value; };
Identifier.prototype.visit = function(visitor) {
  return visitor.visitIdentifier(this);
}
// ********** Code for DeclaredIdentifier **************
$inherits(DeclaredIdentifier, Expression);
function DeclaredIdentifier(type, name, isFinal, span) {
  this.name = name;
  this.type = type;
  this.isFinal = isFinal;
  Expression.call(this, span);
}
DeclaredIdentifier.prototype.get$type = function() { return this.type; };
DeclaredIdentifier.prototype.get$name = function() { return this.name; };
DeclaredIdentifier.prototype.set$name = function(value) { return this.name = value; };
DeclaredIdentifier.prototype.get$isFinal = function() { return this.isFinal; };
DeclaredIdentifier.prototype.visit = function(visitor) {
  return visitor.visitDeclaredIdentifier(this);
}
// ********** Code for Type **************
$inherits(Type, Element);
function Type(name) {
  this.isTested = false;
  this._foundMembers = new HashMapImplementation();
  this.isChecked = false;
  this.isWritten = false;
  this.varStubs = new HashMapImplementation();
  Element.call(this, name, null);
}
Type.prototype.get$typeCheckCode = function() { return this.typeCheckCode; };
Type.prototype.get$varStubs = function() { return this.varStubs; };
Type.prototype.markUsed = function() {

}
Type.prototype.get$typeMember = function() {
  if (this._typeMember == null) {
    this._typeMember = new TypeMember(this);
  }
  return this._typeMember;
}
Type.prototype.getMember = function(name) {
  return null;
}
Type.prototype.get$subtypes = function() {
  return null;
}
Type.prototype.get$isVar = function() {
  return false;
}
Type.prototype.get$isTop = function() {
  return false;
}
Type.prototype.get$isObject = function() {
  return false;
}
Type.prototype.get$isString = function() {
  return false;
}
Type.prototype.get$isBool = function() {
  return false;
}
Type.prototype.get$isFunction = function() {
  return false;
}
Type.prototype.get$isNum = function() {
  return false;
}
Type.prototype.get$isVoid = function() {
  return false;
}
Type.prototype.get$isNullable = function() {
  return true;
}
Type.prototype.get$isVarOrFunction = function() {
  return this.get$isVar() || this.get$isFunction();
}
Type.prototype.get$isVarOrObject = function() {
  return this.get$isVar() || this.get$isObject();
}
Type.prototype.getCallMethod = function() {
  return null;
}
Type.prototype.get$isClosed = function() {
  return this.get$isString() || this.get$isBool() || this.get$isNum() || this.get$isFunction() || this.get$isVar();
}
Type.prototype.get$isUsed = function() {
  return false;
}
Type.prototype.get$isGeneric = function() {
  return false;
}
Type.prototype.get$nativeType = function() {
  return null;
}
Type.prototype.get$isHiddenNativeType = function() {
  return (this.get$nativeType() != null && this.get$nativeType().isConstructorHidden);
}
Type.prototype.get$isSingletonNative = function() {
  return (this.get$nativeType() != null && this.get$nativeType().isSingleton);
}
Type.prototype.get$isJsGlobalObject = function() {
  return (this.get$nativeType() != null && this.get$nativeType().isJsGlobalObject);
}
Type.prototype.get$hasTypeParams = function() {
  return false;
}
Type.prototype.get$typeofName = function() {
  return null;
}
Type.prototype.get$fullname = function() {
  return null != this.get$library().name ? ("" + this.get$library().name + "." + this.name) : this.name;
}
Type.prototype.get$members = function() {
  return null;
}
Type.prototype.get$definition = function() {
  return null;
}
Type.prototype.get$factories = function() {
  return null;
}
Type.prototype.get$typeArgsInOrder = function() {
  return const$0007;
}
Type.prototype.get$genericType = function() {
  return this;
}
Type.prototype.get$isConcreteGeneric = function() {
  return $ne$(this.get$genericType(), this);
}
Type.prototype.get$interfaces = function() {
  return null;
}
Type.prototype.get$parent = function() {
  return null;
}
Type.prototype.get$nativeName = function() {
  return this.get$isNative() ? this.get$definition().get$nativeType().name : this.get$jsname();
}
Type.prototype.get$avoidNativeName = function() {
  return this.get$isHiddenNativeType();
}
Type.prototype.get$hasNativeSubtypes = function() {
  if (this._hasNativeSubtypes == null) {
    this._hasNativeSubtypes = this.get$subtypes().some((function (t) {
      return t.get$isNative();
    })
    );
  }
  return this._hasNativeSubtypes;
}
Type.prototype._checkExtends = function() {
  var typeParams = this.get$genericType().typeParameters;
  if ($ne$(typeParams)) {
    for (var i = (0);
     i < typeParams.get$length(); i++) {
      if ($ne$(typeParams.$index(i).get$extendsType())) {
        this.get$typeArgsInOrder().$index(i).get$dynamic().ensureSubtypeOf(typeParams.$index(i).get$extendsType(), typeParams.$index(i).get$span(), false);
      }
    }
  }
  if (this.get$interfaces() != null) {
    var $$list = this.get$interfaces();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var i = $$i.next();
      i._checkExtends();
    }
  }
}
Type.prototype._checkOverride = function(member) {
  var parentMember = this._getMemberInParents(member.name);
  if ($ne$(parentMember)) {
    if (!member.get$isPrivate() || $eq$(member.get$library(), parentMember.get$library())) {
      member.override(parentMember);
    }
  }
}
Type.prototype._createNotEqualMember = function() {
  var eq = this.get$members().$index(":eq");
  if (eq == null) {
    return;
  }
  var ne = new MethodMember(":ne", this, eq.definition);
  ne.set$returnType(eq.returnType);
  ne.set$parameters(eq.parameters);
  ne.set$isStatic(eq.isStatic);
  ne.set$isAbstract(eq.isAbstract);
  this.get$members().$setindex(":ne", ne);
}
Type.prototype._getMemberInParents = function(memberName) {
  if (this.get$isClass()) {
    if (this.get$parent() != null) {
      return this.get$parent().getMember(memberName);
    }
    else {
      return null;
    }
  }
  else {
    if (this.get$interfaces() != null && this.get$interfaces().get$length() > (0)) {
      var $$list = this.get$interfaces();
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var i = $$i.next();
        var ret = i.getMember(memberName);
        if ($ne$(ret)) {
          return ret;
        }
      }
    }
    return $globals.world.objectType.getMember(memberName);
  }
}
Type.prototype.ensureSubtypeOf = function(other, span, typeErrors) {
  if (!this.isSubtypeOf(other)) {
    var msg = ("type " + this.name + " is not a subtype of " + other.name);
    if (typeErrors) {
      $globals.world.error(msg, span);
    }
    else {
      $globals.world.warning(msg, span);
    }
  }
}
Type.prototype.needsVarCall = function(args) {
  if (this.get$isVarOrFunction()) {
    return true;
  }
  var call = this.getCallMethod();
  if ($ne$(call)) {
    if (args.get$length() != call.get$parameters().get$length() || !call.namesInOrder(args)) {
      return true;
    }
  }
  return false;
}
Type.prototype.get$needsVarCall = function() {
  return this.needsVarCall.bind(this);
}
Type.union = function(x, y) {
  if ($eq$(x, y)) return x;
  if (x.get$isNum() && y.get$isNum()) return $globals.world.numType;
  if (x.get$isString() && y.get$isString()) return $globals.world.stringType;
  return $globals.world.varType;
}
Type.prototype.isAssignable = function(other) {
  return this.isSubtypeOf(other) || other.isSubtypeOf(this);
}
Type.prototype._isDirectSupertypeOf = function(other) {
  var $this = this; // closure support
  if (other.get$isClass()) {
    return $eq$(other.get$parent(), this) || this.get$isObject() && other.get$parent() == null;
  }
  else {
    if (other.get$interfaces() == null || other.get$interfaces().isEmpty()) {
      return this.get$isObject();
    }
    else {
      return other.get$interfaces().some((function (i) {
        return $eq$(i, $this);
      })
      );
    }
  }
}
Type.prototype.isSubtypeOf = function(other) {
  var $0;
  if ($eq$(this, other)) return true;
  if (this.get$isVar() || other.get$isVar()) return true;
  if (other._isDirectSupertypeOf(this)) return true;
  var call = this.getCallMethod();
  var otherCall = other.getCallMethod();
  if ($ne$(call) && $ne$(otherCall)) {
    return Type._isFunctionSubtypeOf(call, otherCall);
  }
  if ((($0 = this.get$genericType()) == null ? null == (other.get$genericType()) : $0 === other.get$genericType())) {
    for (var i = (0);
     i < this.get$typeArgsInOrder().get$length(); i++) {
      if (!this.get$typeArgsInOrder().$index(i).get$dynamic().isSubtypeOf(other.get$typeArgsInOrder().$index(i))) {
        return false;
      }
    }
    return true;
  }
  if (this.get$parent() != null && this.get$parent().isSubtypeOf(other)) {
    return true;
  }
  if (this.get$interfaces() != null && this.get$interfaces().some((function (i) {
    return i.isSubtypeOf(other);
  })
  )) {
    return true;
  }
  return false;
}
Type.prototype.hashCode = function() {
  var libraryCode = this.get$library() == null ? (1) : this.get$library().hashCode();
  var nameCode = this.name == null ? (1) : this.name.hashCode();
  return $bit_xor$(($shl$(libraryCode, (4))), nameCode);
}
Type.prototype.$eq = function(other) {
  return (other instanceof Type) && $eq$(other.get$name(), this.name) && $eq$(this.get$library(), other.get$library());
}
Type._isFunctionSubtypeOf = function(t, s) {
  if (!s.returnType.get$isVoid() && !s.returnType.isAssignable(t.returnType)) {
    return false;
  }
  var tp = t.parameters;
  var sp = s.parameters;
  if (tp.get$length() < sp.get$length()) return false;
  for (var i = (0);
   i < sp.get$length(); i++) {
    if ($ne$(tp.$index(i).get$isOptional(), sp.$index(i).get$isOptional())) return false;
    if (tp.$index(i).get$isOptional() && $ne$(tp.$index(i).get$name(), sp.$index(i).get$name())) return false;
    if (!tp.$index(i).get$type().isAssignable(sp.$index(i).get$type())) return false;
  }
  if (tp.get$length() > sp.get$length() && !tp.$index(sp.get$length()).get$isOptional()) return false;
  return true;
}
// ********** Code for ParameterType **************
$inherits(ParameterType, Type);
function ParameterType(name, typeParameter) {
  this.typeParameter = typeParameter;
  Type.call(this, name);
}
ParameterType.prototype.get$typeParameter = function() { return this.typeParameter; };
ParameterType.prototype.get$extendsType = function() { return this.extendsType; };
ParameterType.prototype.get$isClass = function() {
  return false;
}
ParameterType.prototype.get$library = function() {
  return null;
}
ParameterType.prototype.get$span = function() {
  return this.typeParameter.span;
}
ParameterType.prototype.get$constructors = function() {
  $globals.world.internalError("no constructors on type parameters yet");
}
ParameterType.prototype.getCallMethod = function() {
  return this.extendsType.getCallMethod();
}
ParameterType.prototype.genMethod = function(method) {
  this.extendsType.genMethod(method);
}
ParameterType.prototype.isSubtypeOf = function(other) {
  return true;
}
ParameterType.prototype.getConstructor = function(constructorName) {
  $globals.world.internalError("no constructors on type parameters yet");
}
ParameterType.prototype.getOrMakeConcreteType = function(typeArgs) {
  $globals.world.internalError("no concrete types of type parameters yet", this.get$span());
}
ParameterType.prototype.addDirectSubtype = function(type) {
  $globals.world.internalError("no subtypes of type parameters yet", this.get$span());
}
ParameterType.prototype.resolve = function() {
  if (this.typeParameter.extendsType != null) {
    this.extendsType = this.get$enclosingElement().resolveType(this.typeParameter.extendsType, true, true);
  }
  else {
    this.extendsType = $globals.world.objectType;
  }
}
// ********** Code for NonNullableType **************
$inherits(NonNullableType, Type);
function NonNullableType(type) {
  this.type = type;
  Type.call(this, type.name);
}
NonNullableType.prototype.get$type = function() { return this.type; };
NonNullableType.prototype.get$isNullable = function() {
  return false;
}
NonNullableType.prototype.get$isBool = function() {
  return this.type.get$isBool();
}
NonNullableType.prototype.get$isUsed = function() {
  return false;
}
NonNullableType.prototype.isSubtypeOf = function(other) {
  return $eq$(this, other) || $eq$(this.type, other) || this.type.isSubtypeOf(other);
}
NonNullableType.prototype.resolveType = function(node, isRequired, allowTypeParams) {
  return this.type.resolveType(node, isRequired, allowTypeParams);
}
NonNullableType.prototype.addDirectSubtype = function(subtype) {
  this.type.addDirectSubtype(subtype);
}
NonNullableType.prototype.markUsed = function() {
  this.type.markUsed();
}
NonNullableType.prototype.genMethod = function(method) {
  this.type.genMethod(method);
}
NonNullableType.prototype.get$span = function() {
  return this.type.get$span();
}
NonNullableType.prototype.getMember = function(name) {
  return this.type.getMember(name);
}
NonNullableType.prototype.getConstructor = function(name) {
  return this.type.getConstructor(name);
}
NonNullableType.prototype.getOrMakeConcreteType = function(typeArgs) {
  return this.type.getOrMakeConcreteType(typeArgs);
}
NonNullableType.prototype.get$constructors = function() {
  return this.type.get$constructors();
}
NonNullableType.prototype.get$isClass = function() {
  return this.type.get$isClass();
}
NonNullableType.prototype.get$library = function() {
  return this.type.get$library();
}
NonNullableType.prototype.getCallMethod = function() {
  return this.type.getCallMethod();
}
NonNullableType.prototype.get$isGeneric = function() {
  return this.type.get$isGeneric();
}
NonNullableType.prototype.get$hasTypeParams = function() {
  return this.type.get$hasTypeParams();
}
NonNullableType.prototype.get$typeofName = function() {
  return this.type.get$typeofName();
}
NonNullableType.prototype.get$jsname = function() {
  return this.type.get$jsname();
}
NonNullableType.prototype.get$members = function() {
  return this.type.get$members();
}
NonNullableType.prototype.get$definition = function() {
  return this.type.get$definition();
}
NonNullableType.prototype.get$factories = function() {
  return this.type.get$factories();
}
NonNullableType.prototype.get$typeArgsInOrder = function() {
  return this.type.get$typeArgsInOrder();
}
NonNullableType.prototype.get$genericType = function() {
  return this.type.get$genericType();
}
NonNullableType.prototype.get$interfaces = function() {
  return this.type.get$interfaces();
}
NonNullableType.prototype.get$parent = function() {
  return this.type.get$parent();
}
NonNullableType.prototype.get$isNative = function() {
  return this.type.get$isNative();
}
// ********** Code for DefinedType **************
$inherits(DefinedType, Type);
function DefinedType(name, library, definition, isClass) {
  this.isUsed = false;
  this.directSubtypes = new HashSetImplementation_Type();
  this.isNative = false;
  this.library = library;
  this.isClass = isClass;
  this.constructors = new HashMapImplementation();
  this.factories = new FactoryMap();
  this.members = new HashMapImplementation();
  Type.call(this, name);
  this.setDefinition(definition);
}
DefinedType.prototype.get$definition = function() { return this.definition; };
DefinedType.prototype.get$library = function() { return this.library; };
DefinedType.prototype.get$isClass = function() { return this.isClass; };
DefinedType.prototype.get$parent = function() {
  return this._parent;
}
DefinedType.prototype.set$parent = function(p) {
  this._parent = p;
}
DefinedType.prototype.get$interfaces = function() { return this.interfaces; };
DefinedType.prototype.set$interfaces = function(value) { return this.interfaces = value; };
DefinedType.prototype.get$directSubtypes = function() { return this.directSubtypes; };
DefinedType.prototype.get$typeParameters = function() { return this.typeParameters; };
DefinedType.prototype.get$typeArgsInOrder = function() { return this.typeArgsInOrder; };
DefinedType.prototype.set$typeArgsInOrder = function(value) { return this.typeArgsInOrder = value; };
DefinedType.prototype.get$constructors = function() { return this.constructors; };
DefinedType.prototype.get$members = function() { return this.members; };
DefinedType.prototype.get$factories = function() { return this.factories; };
DefinedType.prototype.get$_concreteTypes = function() { return this._concreteTypes; };
DefinedType.prototype.get$isUsed = function() { return this.isUsed; };
DefinedType.prototype.get$isNative = function() { return this.isNative; };
DefinedType.prototype.set$baseGenericType = function(value) { return this.baseGenericType = value; };
DefinedType.prototype.get$genericType = function() {
  return null == this.baseGenericType ? this : this.baseGenericType;
}
DefinedType.prototype.setDefinition = function(def) {
  this.definition = def;
  if ((this.definition instanceof TypeDefinition) && this.definition.get$nativeType() != null) {
    this.isNative = true;
  }
  if (this.definition != null && $ne$(this.definition.get$typeParameters())) {
    this._concreteTypes = new HashMapImplementation();
    this.typeParameters = this.definition.get$typeParameters();
    this.typeArgsInOrder = new Array(this.typeParameters.get$length());
    for (var i = (0);
     i < this.typeArgsInOrder.get$length(); i++) {
      this.typeArgsInOrder.$setindex(i, $globals.world.varType);
    }
  }
  else {
    this.typeArgsInOrder = const$0007;
  }
}
DefinedType.prototype.get$nativeType = function() {
  return (this.definition != null ? this.definition.get$nativeType() : null);
}
DefinedType.prototype.get$isVar = function() {
  return $eq$(this, $globals.world.varType);
}
DefinedType.prototype.get$isVoid = function() {
  return $eq$(this, $globals.world.voidType);
}
DefinedType.prototype.get$isTop = function() {
  return this.name == null;
}
DefinedType.prototype.get$isObject = function() {
  return $eq$(this, $globals.world.objectType);
}
DefinedType.prototype.get$isString = function() {
  return $eq$(this, $globals.world.stringType) || $eq$(this, $globals.world.stringImplType);
}
DefinedType.prototype.get$isBool = function() {
  return $eq$(this, $globals.world.boolType);
}
DefinedType.prototype.get$isFunction = function() {
  return $eq$(this, $globals.world.functionType) || $eq$(this, $globals.world.functionImplType);
}
DefinedType.prototype.get$isGeneric = function() {
  return this.typeParameters != null;
}
DefinedType.prototype.get$span = function() {
  return this.definition == null ? null : this.definition.span;
}
DefinedType.prototype.get$typeofName = function() {
  if (!this.library.get$isCore()) return null;
  if (this.get$isBool()) return "boolean";
  else if (this.get$isNum()) return "number";
  else if (this.get$isString()) return "string";
  else if (this.get$isFunction()) return "function";
  else return null;
}
DefinedType.prototype.get$isNum = function() {
  return $eq$(this, $globals.world.numType) || $eq$(this, $globals.world.intType) || $eq$(this, $globals.world.doubleType) || $eq$(this, $globals.world.numImplType);
}
DefinedType.prototype.getCallMethod = function() {
  return this.get$genericType().members.$index(":call");
}
DefinedType.prototype.getAllMembers = function() {
  return HashMapImplementation.HashMapImplementation$from$factory(this.members);
}
DefinedType.prototype.markUsed = function() {
  if (this.isUsed) return;
  this.isUsed = true;
  this._checkExtends();
  if (this._lazyGenMethods != null) {
    var $$list = orderValuesByKeys(this._lazyGenMethods);
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var method = $$i.next();
      $globals.world.gen.genMethod(method);
    }
    this._lazyGenMethods = null;
  }
  if (this.get$parent() != null) this.get$parent().markUsed();
}
DefinedType.prototype.genMethod = function(method) {
  if (this.isUsed || this.baseGenericType != null) {
    $globals.world.gen.genMethod(method);
  }
  else if (this.isClass) {
    if (this._lazyGenMethods == null) this._lazyGenMethods = new HashMapImplementation();
    this._lazyGenMethods.$setindex(method.name, method);
  }
}
DefinedType.prototype._resolveInterfaces = function(types) {
  if (types == null) return [];
  var interfaces = [];
  for (var $$i = types.iterator(); $$i.hasNext(); ) {
    var type = $$i.next();
    var resolvedInterface = this.resolveType(type, true, true);
    if (resolvedInterface.get$isClosed() && !(this.library.get$isCore() || this.library.get$isCoreImpl())) {
      $globals.world.error($add$(("cannot implement \"" + resolvedInterface.get$name() + "\": "), "only native implementation allowed"), type.get$span());
    }
    resolvedInterface.addDirectSubtype(this);
    interfaces.add(resolvedInterface);
  }
  return interfaces;
}
DefinedType.prototype.addDirectSubtype = function(type) {
  this.directSubtypes.add(type);
  if (this.baseGenericType != null) {
    this.baseGenericType.addDirectSubtype(type);
  }
}
DefinedType.prototype.get$subtypes = function() {
  if (this._subtypes == null) {
    this._subtypes = new HashSetImplementation_Type();
    var $$list = this.directSubtypes;
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var st = $$i.next();
      this._subtypes.add(st);
      this._subtypes.addAll(st.get$subtypes());
    }
  }
  return this._subtypes;
}
DefinedType.prototype._cycleInClassExtends = function() {
  var seen = new HashSetImplementation();
  seen.add(this);
  var ancestor = this.get$parent();
  while ($ne$(ancestor)) {
    if ((null == ancestor ? null == (this) : ancestor === this)) {
      return true;
    }
    if (seen.contains$1(ancestor)) {
      return false;
    }
    seen.add(ancestor);
    ancestor = ancestor.get$parent();
  }
  return false;
}
DefinedType.prototype._cycleInInterfaceExtends = function() {
  var $this = this; // closure support
  var seen = new HashSetImplementation();
  seen.add(this);
  function _helper(ancestor) {
    if ($eq$(ancestor)) return false;
    if ((null == ancestor ? null == ($this) : ancestor === $this)) return true;
    if (seen.contains$1(ancestor)) {
      return false;
    }
    seen.add(ancestor);
    if (ancestor.get$interfaces() != null) {
      var $$list = ancestor.get$interfaces();
      for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
        var parent = $$i.next();
        if (_helper(parent)) return true;
      }
    }
    return false;
  }
  for (var i = (0);
   i < this.interfaces.get$length(); i++) {
    if (_helper(this.interfaces.$index(i))) return i;
  }
  return (-1);
}
DefinedType.prototype.resolve = function() {
  if ((this.definition instanceof TypeDefinition)) {
    var typeDef = this.definition;
    if (this.isClass) {
      if (typeDef.extendsTypes != null && typeDef.extendsTypes.get$length() > (0)) {
        if (typeDef.extendsTypes.get$length() > (1)) {
          $globals.world.error("more than one base class", typeDef.extendsTypes.$index((1)).span);
        }
        var extendsTypeRef = typeDef.extendsTypes.$index((0));
        if ((extendsTypeRef instanceof GenericTypeReference)) {
          var g = extendsTypeRef;
          this.set$parent(this.resolveType(g.baseType, true, true));
        }
        this.set$parent(this.resolveType(extendsTypeRef, true, true));
        if (!this.get$parent().get$isClass()) {
          $globals.world.error("class may not extend an interface - use implements", typeDef.extendsTypes.$index((0)).span);
        }
        this.get$parent().addDirectSubtype(this);
        if (this._cycleInClassExtends()) {
          $globals.world.error(("class \"" + this.name + "\" has a cycle in its inheritance chain"), extendsTypeRef.get$span());
        }
      }
      else {
        if (!this.get$isObject()) {
          this.set$parent($globals.world.objectType);
          this.get$parent().addDirectSubtype(this);
        }
      }
      this.interfaces = this._resolveInterfaces(typeDef.implementsTypes);
      if (typeDef.defaultType != null) {
        $globals.world.error("default not allowed on classes", typeDef.defaultType.span);
      }
    }
    else {
      if (typeDef.implementsTypes != null && typeDef.implementsTypes.get$length() > (0)) {
        $globals.world.error("implements not allowed on interfaces (use extends)", typeDef.implementsTypes.$index((0)).span);
      }
      this.interfaces = this._resolveInterfaces(typeDef.extendsTypes);
      var res = this._cycleInInterfaceExtends();
      if ($gte$(res, (0))) {
        $globals.world.error(("interface \"" + this.name + "\" has a cycle in its inheritance chain"), typeDef.extendsTypes.$index(res).span);
      }
      if (typeDef.defaultType != null) {
        this.defaultType = this.resolveType(typeDef.defaultType.baseType, true, true);
        if (this.defaultType == null) {
          $globals.world.warning("unresolved default class", typeDef.defaultType.span);
        }
        else {
          if (this.baseGenericType != null) {
            if (!this.defaultType.get$isGeneric()) {
              $globals.world.error("default type of generic interface must be generic", typeDef.defaultType.span);
            }
            this.defaultType = this.defaultType.getOrMakeConcreteType(this.typeArgsInOrder);
          }
        }
      }
    }
  }
  else if ((this.definition instanceof FunctionTypeDefinition)) {
    this.interfaces = [$globals.world.functionType];
  }
  this._resolveTypeParams(this.typeParameters);
  if (this.get$isObject()) this._createNotEqualMember();
  if ($ne$(this.baseGenericType, $globals.world.listFactoryType)) $globals.world._addType(this);
  var $$list = this.constructors.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var c = $$i.next();
    c.resolve();
  }
  var $$list = this.members.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var m = $$i.next();
    m.resolve();
  }
  this.factories.forEach((function (f) {
    return f.resolve();
  })
  );
  if (this.get$isJsGlobalObject()) {
    var $$list = this.members.getValues();
    for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
      var m = $$i.next();
      if (!m.get$isStatic()) $globals.world._addTopName(new ExistingJsGlobal(m.get$name(), m));
    }
  }
}
DefinedType.prototype._resolveTypeParams = function(params) {
  if (params == null) return;
  for (var $$i = params.iterator(); $$i.hasNext(); ) {
    var tp = $$i.next();
    tp.set$enclosingElement(this);
    tp.resolve();
  }
}
DefinedType.prototype.addMethod = function(methodName, definition) {
  if (methodName == null) methodName = definition.name.name;
  var method = new MethodMember(methodName, this, definition);
  if (method.get$isConstructor()) {
    if (this.constructors.containsKey(method.get$constructorName())) {
      $globals.world.error(("duplicate constructor definition of " + method.get$name()), definition.span);
      return;
    }
    this.constructors.$setindex(method.get$constructorName(), method);
    return;
  }
  if (definition.modifiers != null && definition.modifiers.get$length() == (1) && definition.modifiers.$index((0)).kind == (74)) {
    if (this.factories.getFactory(method.get$constructorName(), method.get$name()) != null) {
      $globals.world.error(("duplicate factory definition of \"" + method.get$name() + "\""), definition.span);
      return;
    }
    this.factories.addFactory(method.get$constructorName(), method.get$name(), method);
    return;
  }
  if (methodName.startsWith("get:") || methodName.startsWith("set:")) {
    var propName = methodName.substring((4));
    var prop = this.members.$index(propName);
    if ($eq$(prop)) {
      prop = new PropertyMember(propName, this);
      this.members.$setindex(propName, prop);
    }
    if (!(prop instanceof PropertyMember)) {
      $globals.world.error(("property conflicts with field \"" + propName + "\""), definition.span);
      return;
    }
    if (methodName[(0)] == "g") {
      if (prop.get$getter() != null) {
        $globals.world.error(("duplicate getter definition for \"" + propName + "\""), definition.span);
      }
      prop.set$getter(method);
    }
    else {
      if (prop.get$setter() != null) {
        $globals.world.error(("duplicate setter definition for \"" + propName + "\""), definition.span);
      }
      prop.set$setter(method);
    }
    return;
  }
  if (this.members.containsKey(methodName)) {
    $globals.world.error(("duplicate method definition of \"" + method.get$name() + "\""), definition.span);
    return;
  }
  this.members.$setindex(methodName, method);
}
DefinedType.prototype.addField = function(definition) {
  for (var i = (0);
   i < definition.names.get$length(); i++) {
    var name = definition.names.$index(i).name;
    if (this.members.containsKey(name)) {
      $globals.world.error(("duplicate field definition of \"" + name + "\""), definition.span);
      return;
    }
    var value = null;
    if (definition.values != null) {
      value = definition.values.$index(i);
    }
    var field = new FieldMember(name, this, definition, value, this.isNative);
    this.members.$setindex(name, field);
  }
}
DefinedType.prototype.getFactory = function(type, constructorName) {
  if (this.baseGenericType != null) {
    var rr = this.baseGenericType.get$factories().getFactory(type.get$genericType().name, constructorName);
    if ($ne$(rr)) {
      $globals.world.info(("need to remap factory on " + this.name + " from " + rr.get$declaringType().name));
      return rr;
    }
    else {
      var ret = this.getConstructor(constructorName);
      return ret;
    }
  }
  var ret = this.factories.getFactory(type.get$genericType().name, constructorName);
  if ($ne$(ret)) return ret;
  ret = this.factories.getFactory(this.name, constructorName);
  if ($ne$(ret)) return ret;
  ret = this.constructors.$index(constructorName);
  if ($ne$(ret)) return ret;
  return this._tryCreateDefaultConstructor(constructorName);
}
DefinedType.prototype.getConstructor = function(constructorName) {
  if (this.baseGenericType != null) {
    var rr = this.constructors.$index(constructorName);
    if ($ne$(rr)) return rr;
    rr = this.baseGenericType.get$constructors().$index(constructorName);
    if ($ne$(rr)) {
      if (this.defaultType != null) {
        var ret = this.defaultType.getFactory(this, constructorName);
        return ret;
      }
    }
    else {
      rr = this.baseGenericType.get$factories().getFactory(this.baseGenericType.name, constructorName);
    }
    if ($eq$(rr)) {
      rr = this.baseGenericType.get$dynamic()._tryCreateDefaultConstructor(constructorName);
    }
    if ($eq$(rr)) return null;
    var rr1 = rr.makeConcrete(this);
    rr1.resolve();
    this.constructors.$setindex(constructorName, rr1);
    return rr1;
  }
  var ret = this.constructors.$index(constructorName);
  if ($ne$(ret)) {
    if (this.defaultType != null) {
      return this.defaultType.getFactory(this, constructorName);
    }
    return ret;
  }
  ret = this.factories.getFactory(this.name, constructorName);
  if ($ne$(ret)) return ret;
  return this._tryCreateDefaultConstructor(constructorName);
}
DefinedType.prototype._tryCreateDefaultConstructor = function(name) {
  if (name == "" && this.definition != null && this.isClass && this.constructors.get$length() == (0)) {
    var span = this.definition.span;
    var inits = null, native_ = null, body = null;
    if (this.isNative) {
      native_ = "";
      inits = null;
    }
    else {
      body = null;
      inits = [new CallExpression(new SuperExpression(span), [], span)];
    }
    var typeDef = this.definition;
    var c = new FunctionDefinition(null, null, typeDef.name, [], inits, native_, body, span);
    this.addMethod(null, c);
    this.constructors.$index("").resolve();
    return this.constructors.$index("");
  }
  return null;
}
DefinedType.prototype.getMember = function(memberName) {
  var member = this._foundMembers.$index(memberName);
  if (member != null) return member;
  if (this.baseGenericType != null) {
    member = this.baseGenericType.getMember(memberName);
    if (member == null) return null;
    if (member.get$isStatic() || $ne$(member.declaringType, this.baseGenericType)) {
      this._foundMembers.$setindex(memberName, member);
      return member;
    }
    var rr = member.makeConcrete(this);
    if (null != member.get$definition() || (member instanceof PropertyMember)) {
      rr.resolve();
    }
    else {
      $globals.world.info(("no definition for " + member.name + " on " + this.name));
    }
    this.members.$setindex(memberName, rr);
    this._foundMembers.$setindex(memberName, rr);
    return rr;
  }
  member = this.members.$index(memberName);
  if (member != null) {
    this._checkOverride(member);
    this._foundMembers.$setindex(memberName, member);
    return member;
  }
  if (this.get$isTop()) {
    var libType = this.library.findTypeByName(memberName);
    if ($ne$(libType)) {
      member = libType.get$typeMember();
      this._foundMembers.$setindex(memberName, member);
      return member;
    }
  }
  member = this._getMemberInParents(memberName);
  this._foundMembers.$setindex(memberName, member);
  return member;
}
DefinedType.prototype.getOrMakeConcreteType = function(typeArgs) {
  var jsnames = [];
  var names = [];
  var typeMap = new HashMapImplementation();
  var allVar = true;
  for (var i = (0);
   i < typeArgs.get$length(); i++) {
    var typeArg = typeArgs.$index(i);
    if ((typeArg instanceof ParameterType)) {
      typeArg = $globals.world.varType;
      typeArgs.$setindex(i, typeArg);
    }
    if (!typeArg.get$isVar()) allVar = false;
    var paramName = this.typeParameters.$index(i).name;
    typeMap.$setindex(paramName, typeArg);
    names.add(typeArg.get$fullname());
    jsnames.add(typeArg.get$jsname());
  }
  if (allVar) return this;
  var jsname = ("" + this.get$jsname() + "_" + Strings.join(jsnames, "$"));
  var simpleName = ("" + this.name + "<" + Strings.join(names, ", ") + ">");
  var ret = this._concreteTypes.$index(simpleName);
  if ($eq$(ret)) {
    ret = new DefinedType(simpleName, this.library, this.definition, this.isClass);
    ret.set$baseGenericType(this);
    ret.set$typeArgsInOrder(typeArgs);
    ret.set$_jsname(jsname);
    this._concreteTypes.$setindex(simpleName, ret);
    ret.resolve();
  }
  return ret;
}
DefinedType.prototype.getCallStub = function(args) {
  var name = _getCallStubName("call", args);
  var stub = this.varStubs.$index(name);
  if ($eq$(stub)) {
    stub = new VarFunctionStub(name, args);
    this.varStubs.$setindex(name, stub);
  }
  return stub;
}
// ********** Code for NativeType **************
function NativeType(name) {
  this.isConstructorHidden = false;
  this.isSingleton = false;
  this.isJsGlobalObject = false;
  this.name = name;
  while (true) {
    if (this.name.startsWith("@")) {
      this.name = this.name.substring((1));
      this.isJsGlobalObject = true;
    }
    else if (this.name.startsWith("*")) {
      this.name = this.name.substring((1));
      this.isConstructorHidden = true;
    }
    else {
      break;
    }
  }
  if (this.name.startsWith("=")) {
    this.name = this.name.substring((1));
    this.isSingleton = true;
  }
}
NativeType.prototype.get$name = function() { return this.name; };
NativeType.prototype.set$name = function(value) { return this.name = value; };
// ********** Code for _SharedBackingMap **************
$inherits(_SharedBackingMap, HashMapImplementation);
function _SharedBackingMap() {
  this.shared = (0);
  HashMapImplementation.call(this);
}
_SharedBackingMap._SharedBackingMap$from$factory = function(other) {
  var result = new _SharedBackingMap();
  other.forEach((function (k, v) {
    result.$setindex(k, v);
  })
  );
  return result;
}
// ********** Code for _SharedBackingMap_dart_core_String$VariableValue **************
$inherits(_SharedBackingMap_dart_core_String$VariableValue, _SharedBackingMap);
function _SharedBackingMap_dart_core_String$VariableValue() {
  this.shared = (0);
  HashMapImplementation_dart_core_String$VariableValue.call(this);
}
// ********** Code for CopyOnWriteMap **************
CopyOnWriteMap._wrap$ctor = function(_map) {
  this._lang_map = _map;
}
CopyOnWriteMap._wrap$ctor.prototype = CopyOnWriteMap.prototype;
function CopyOnWriteMap() {}
CopyOnWriteMap.prototype.is$Map = function(){return true};
CopyOnWriteMap.prototype.clone = function() {
  var $0;
  ($0 = this._lang_map).shared = $0.shared + (1);
  return new CopyOnWriteMap._wrap$ctor(this._lang_map);
}
CopyOnWriteMap.prototype._ensureWritable = function() {
  var $0;
  if (this._lang_map.shared > (0)) {
    ($0 = this._lang_map).shared = $0.shared - (1);
    this._lang_map = _SharedBackingMap._SharedBackingMap$from$factory(this._lang_map);
  }
}
CopyOnWriteMap.prototype.$setindex = function(key, value) {
  this._ensureWritable();
  this._lang_map.$setindex(key, value);
}
CopyOnWriteMap.prototype.putIfAbsent = function(key, ifAbsent) {
  this._ensureWritable();
  return this._lang_map.putIfAbsent(key, ifAbsent);
}
CopyOnWriteMap.prototype.remove = function(key) {
  this._ensureWritable();
  return this._lang_map.remove(key);
}
CopyOnWriteMap.prototype.$index = function(key) {
  return this._lang_map.$index(key);
}
CopyOnWriteMap.prototype.isEmpty = function() {
  return this._lang_map.isEmpty();
}
CopyOnWriteMap.prototype.get$length = function() {
  return this._lang_map.get$length();
}
CopyOnWriteMap.prototype.forEach = function(f) {
  return this._lang_map.forEach(f);
}
CopyOnWriteMap.prototype.getKeys = function() {
  return this._lang_map.getKeys();
}
CopyOnWriteMap.prototype.getValues = function() {
  return this._lang_map.getValues();
}
CopyOnWriteMap.prototype.containsKey = function(key) {
  return this._lang_map.containsKey(key);
}
CopyOnWriteMap.prototype.remove$1 = CopyOnWriteMap.prototype.remove;
// ********** Code for CopyOnWriteMap_dart_core_String$VariableValue **************
$inherits(CopyOnWriteMap_dart_core_String$VariableValue, CopyOnWriteMap);
function CopyOnWriteMap_dart_core_String$VariableValue() {
  this._lang_map = new _SharedBackingMap_dart_core_String$VariableValue();
}
CopyOnWriteMap_dart_core_String$VariableValue.prototype.is$Map = function(){return true};
CopyOnWriteMap_dart_core_String$VariableValue.prototype.remove$1 = CopyOnWriteMap_dart_core_String$VariableValue.prototype.remove;
// ********** Code for Value **************
function Value(type, code, span) {
  this.type = type;
  this.span = span;
  this.code = code;
  if (this.get$type() == null) $globals.world.internalError("type passed as null", this.span);
}
Value.prototype.get$type = function() { return this.type; };
Value.prototype.get$code = function() { return this.code; };
Value.prototype.get$span = function() { return this.span; };
Value.prototype.get$isType = function() {
  return false;
}
Value.prototype.get$isSuper = function() {
  return false;
}
Value.prototype.get$isConst = function() {
  return false;
}
Value.prototype.get$isFinal = function() {
  return false;
}
Value.prototype.get$needsTemp = function() {
  return true;
}
Value.prototype.get$staticType = function() {
  return this.get$type();
}
Value.comma = function(x, y) {
  return new Value(y.get$type(), ("(" + x.get$code() + ", " + y.get$code() + ")"), null);
}
Value.union = function(x, y) {
  if (null == y || $eq$(x, y)) return x;
  if (null == x) return y;
  var ret = x._tryUnion(y);
  if ($ne$(ret)) return ret;
  ret = y._tryUnion(x);
  if ($ne$(ret)) return ret;
  return new Value(Type.union(x.get$type(), y.get$type()), null, null);
}
Value.prototype._tryUnion = function(right) {
  return null;
}
Value.prototype.validateInitialized = function(span) {

}
Value.prototype.get_ = function(context, name, node) {
  var member = this._resolveMember(context, name, node);
  if ($ne$(member)) {
    return member._get(context, node, this);
  }
  else {
    return this.invokeNoSuchMethod$3(context, ("get:" + name), node);
  }
}
Value.prototype.set_ = function(context, name, node, value, kind, returnKind) {
  var member = this._resolveMember(context, name, node);
  if ($ne$(member)) {
    var thisValue = this;
    var thisTmp = null;
    var retTmp = null;
    if (kind != (0)) {
      thisTmp = context.getTemp(thisValue);
      thisValue = context.assignTemp(thisTmp, thisValue);
      var lhs = member._get(context, node, thisTmp);
      if (returnKind == (3)) {
        retTmp = context.forceTemp(lhs);
        lhs = context.assignTemp(retTmp, lhs);
      }
      value = lhs.binop(kind, value, context, node);
    }
    if (returnKind == (2)) {
      retTmp = context.forceTemp(value);
      value = context.assignTemp(retTmp, value);
    }
    var ret = member._set(context, node, thisValue, value);
    if ($ne$(thisTmp) && $ne$(thisTmp, this)) context.freeTemp(thisTmp);
    if ($ne$(retTmp)) {
      context.freeTemp(retTmp);
      return Value.comma(ret, retTmp);
    }
    else {
      return ret;
    }
  }
  else {
    return this.invokeNoSuchMethod(context, ("set:" + name), node, new Arguments(null, [value]));
  }
}
Value.prototype.setIndex = function(context, index, node, value, kind, returnKind) {
  var member = this._resolveMember(context, ":setindex", node);
  if ($ne$(member)) {
    var thisValue = this;
    var indexValue = index;
    var thisTmp = null;
    var indexTmp = null;
    var retTmp = null;
    if (returnKind == (2)) {
      retTmp = context.forceTemp(value);
    }
    if (kind != (0)) {
      thisTmp = context.getTemp(this);
      indexTmp = context.getTemp(index);
      thisValue = context.assignTemp(thisTmp, thisValue);
      indexValue = context.assignTemp(indexTmp, indexValue);
      if (returnKind == (3)) {
        retTmp = context.forceTemp(value);
      }
      var lhs = thisTmp.invoke(context, ":index", node, new Arguments(null, [indexTmp]));
      if (returnKind == (3)) {
        lhs = context.assignTemp(retTmp, lhs);
      }
      value = lhs.binop(kind, value, context, node);
    }
    if (returnKind == (2)) {
      value = context.assignTemp(retTmp, value);
    }
    var ret = member.invoke(context, node, thisValue, new Arguments(null, [indexValue, value]));
    if ($ne$(thisTmp) && $ne$(thisTmp, this)) context.freeTemp(thisTmp);
    if ($ne$(indexTmp) && $ne$(indexTmp, index)) context.freeTemp(indexTmp);
    if ($ne$(retTmp)) {
      context.freeTemp(retTmp);
      return Value.comma(ret, retTmp);
    }
    else {
      return ret;
    }
  }
  else {
    return this.invokeNoSuchMethod(context, ":index", node, new Arguments(null, [index, value]));
  }
}
Value.prototype.unop = function(kind, context, node) {
  switch (kind) {
    case (19):

      var newVal = this.convertTo(context, $globals.world.nonNullBool);
      return new Value(newVal.get$type(), ("!" + newVal.get$code()), node.get$span());

    case (42):

      $globals.world.error("no unary add operator in dart", node.get$span());
      break;

    case (43):

      return this.invoke(context, ":negate", node, Arguments.get$EMPTY());

    case (18):

      return this.invoke(context, ":bit_not", node, Arguments.get$EMPTY());

  }
  $globals.world.internalError(("unimplemented: " + node.get$op()), node.get$span());
}
Value.prototype._mayOverrideEqual = function() {
  return this.get$type().get$isVar() || this.get$type().get$isObject() || !this.get$type().getMember(":eq").declaringType.get$isObject();
}
Value.prototype.binop = function(kind, other, context, node) {
  switch (kind) {
    case (35):
    case (34):

      var code = ("" + this.get$code() + " " + node.get$op() + " " + other.get$code());
      return new Value($globals.world.nonNullBool, code, node.get$span());

    case (50):
    case (51):

      var op = kind == (50) ? "==" : "!=";
      if (this.get$code() == "null") {
        return new Value($globals.world.nonNullBool, ("null " + op + " " + other.get$code()), node.get$span());
      }
      else if (other.get$code() == "null") {
        return new Value($globals.world.nonNullBool, ("null " + op + " " + this.get$code()), node.get$span());
      }
      else {
        var ret;
        var check;
        if (this.get$needsTemp()) {
          var tmp = context.forceTemp(this);
          ret = tmp.get$code();
          check = ("(" + ret + " = " + this.get$code() + ") == null");
        }
        else {
          ret = this.get$code();
          check = ("null == " + this.get$code());
        }
        return new Value($globals.world.nonNullBool, ("(" + check + " ? null " + op + " (" + other.get$code() + ") : " + ret + " " + op + "= " + other.get$code() + ")"), node.get$span());
      }

    case (48):

      if (other.get$code() == "null") {
        if (!this._mayOverrideEqual()) {
          return new Value($globals.world.nonNullBool, ("" + this.get$code() + " == " + other.get$code()), node.get$span());
        }
      }
      else if (this.get$code() == "null") {
        return new Value($globals.world.nonNullBool, ("" + this.get$code() + " == " + other.get$code()), node.get$span());
      }
      break;

    case (49):

      if (other.get$code() == "null") {
        if (!this._mayOverrideEqual()) {
          return new Value($globals.world.nonNullBool, ("" + this.get$code() + " != " + other.get$code()), node.get$span());
        }
      }
      else if (this.get$code() == "null") {
        return new Value($globals.world.nonNullBool, ("" + this.get$code() + " != " + other.get$code()), node.get$span());
      }
      break;

  }
  var name = kind == (49) ? ":ne" : TokenKind.binaryMethodName(kind);
  return this.invoke(context, name, node, new Arguments(null, [other]));
}
Value.prototype.invoke = function(context, name, node, args) {
  if (name == ":call") {
    if (this.get$isType()) {
      $globals.world.error("must use \"new\" or \"const\" to construct a new instance", node.span);
    }
    if (this.get$type().needsVarCall(args)) {
      return this._varCall(context, node, args);
    }
  }
  var member = this._resolveMember(context, name, node);
  if ($eq$(member)) {
    return this.invokeNoSuchMethod(context, name, node, args);
  }
  else {
    return member.invoke(context, node, this, args);
  }
}
Value.prototype._hasOverriddenNoSuchMethod = function() {
  var m = this.get$type().getMember("noSuchMethod");
  return $ne$(m) && !m.get$declaringType().get$isObject();
}
Value.prototype.get$isPreciseType = function() {
  return this.get$isSuper() || this.get$isType();
}
Value.prototype._missingMemberError = function(context, name, node) {
  var onStaticType = false;
  if ($ne$(this.get$type(), this.get$staticType())) {
    onStaticType = null != this.get$staticType().getMember(name);
  }
  if (!onStaticType && context.get$showWarnings() && !this._isVarOrParameterType(this.get$staticType()) && !this._hasOverriddenNoSuchMethod()) {
    var typeName = this.get$staticType().name;
    if ($eq$(typeName)) typeName = this.get$staticType().get$library().name;
    var message = ("cannot resolve \"" + name + "\" on \"" + typeName + "\"");
    if (this.get$isType()) {
      $globals.world.error(message, node.span);
    }
    else {
      $globals.world.warning(message, node.span);
    }
  }
}
Value.prototype._tryResolveMember = function(context, name, node) {
  var member = this.get$type().getMember(name);
  if ($eq$(member)) {
    this._missingMemberError(context, name, node);
    return null;
  }
  else {
    if (this.get$isType() && !member.get$isStatic() && context.get$showWarnings()) {
      $globals.world.error("cannot refer to instance member as static", node.span);
      return null;
    }
  }
  if (this.get$isPreciseType() || member.get$isStatic()) {
    return member.get$preciseMemberSet();
  }
  else {
    return member.get$potentialMemberSet();
  }
}
Value.prototype._isVarOrParameterType = function(t) {
  return t.get$isVar() || (t instanceof ParameterType);
}
Value.prototype._shouldBindDynamically = function() {
  return this._isVarOrParameterType(this.get$type()) || $globals.options.forceDynamic && !this.get$isConst();
}
Value.prototype._resolveMember = function(context, name, node) {
  var member = null;
  if (!this._shouldBindDynamically()) {
    member = this._tryResolveMember(context, name, node);
  }
  if ($eq$(member) && !this.get$isSuper() && !this.get$isType()) {
    member = context.findMembers(name);
    if ($eq$(member) && context.get$showWarnings()) {
      var where = "the world";
      if (name.startsWith("_")) {
        where = ("library \"" + context.get$library().name + "\"");
      }
      $globals.world.warning(("" + name + " is not defined anywhere in " + where + "."), node.span);
    }
  }
  return member;
}
Value.prototype.checkFirstClass = function(span) {
  if (this.get$isType()) {
    $globals.world.error("Types are not first class", span);
  }
}
Value.prototype._varCall = function(context, node, args) {
  var stub = $globals.world.functionType.getCallStub(args);
  return stub.invoke(context, node, this, args);
}
Value.prototype.needsConversion = function(toType) {
  var c = this.convertTo(null, toType);
  return $eq$(c) || this.get$code() != c.get$code();
}
Value.prototype.convertTo = function(context, toType) {
  var checked = context != null && context.get$showWarnings();
  var callMethod = toType.getCallMethod();
  if ($ne$(callMethod)) {
    if (checked && !toType.isAssignable(this.get$type())) {
      this.convertWarning(toType);
    }
    return this._maybeWrapFunction(toType, callMethod);
  }
  var fromType = this.get$type();
  if (this.get$type().get$isVar() && (this.get$code() != "null" || !toType.get$isNullable())) {
    fromType = $globals.world.objectType;
  }
  var bothNum = this.get$type().get$isNum() && toType.get$isNum();
  if (!fromType.isSubtypeOf(toType) && !bothNum) {
    if (checked && !toType.isSubtypeOf(this.get$type())) {
      this.convertWarning(toType);
    }
    if ($globals.options.enableTypeChecks) {
      if (context == null) {
        return null;
      }
      return this._typeAssert(context, toType);
    }
  }
  return this._changeStaticType(toType);
}
Value.prototype._changeStaticType = function(toType) {
  return this;
}
Value.prototype._maybeWrapFunction = function(toType, callMethod) {
  var arity = callMethod.parameters.get$length();
  var myCall = this.get$type().getCallMethod();
  var result = this;
  if ($eq$(myCall) || myCall.get$parameters().get$length() != arity) {
    var stub = $globals.world.functionType.getCallStub(Arguments.Arguments$bare$factory(arity));
    result = new Value(toType, ("to$" + stub.get$name() + "(" + this.get$code() + ")"), this.span);
  }
  if ($eq$(toType.get$library(), $globals.world.dom) && $ne$(this.get$type().get$library(), $globals.world.dom)) {
    if (arity == (0)) {
      $globals.world.gen.corejs.useWrap0 = true;
    }
    else {
      $globals.world.gen.corejs.useWrap1 = true;
    }
    result = new Value(toType, ("$wrap_call$" + arity + "(" + result.get$code() + ")"), this.span);
  }
  return result._changeStaticType(toType);
}
Value.prototype._typeAssert = function(context, toType) {
  var $0;
  if ((toType instanceof ParameterType)) {
    var p = toType;
    toType = p.extendsType;
  }
  if (toType.get$isObject() || toType.get$isVar()) {
    $globals.world.internalError(("We thought " + this.get$type().name + " is not a subtype of " + toType.name + "?"));
  }
  function throwTypeError(paramName) {
    return $globals.world.withoutForceDynamic((function () {
      var typeErrorCtor = $globals.world.typeErrorType.getConstructor("_internal");
      $globals.world.gen.corejs.ensureTypeNameOf();
      var result = typeErrorCtor.invoke(context, null, new TypeValue($globals.world.typeErrorType, null), new Arguments(null, [new Value($globals.world.objectType, paramName, null), new Value($globals.world.stringType, ("\"" + toType.name + "\""), null)]));
      $globals.world.gen.corejs.useThrow = true;
      return ("$throw(" + result.get$code() + ")");
    })
    );
  }
  if (toType.get$isNum()) toType = $globals.world.numType;
  var check;
  if (toType.get$isVoid()) {
    check = ("$assert_void(" + this.get$code() + ")");
    if (toType.typeCheckCode == null) {
      toType.typeCheckCode = ("function $assert_void(x) {\n  if (x == null) return null;\n  " + throwTypeError("x") + "\n}");
    }
  }
  else if ($eq$(toType, $globals.world.nonNullBool)) {
    $globals.world.gen.corejs.useNotNullBool = true;
    check = ("$notnull_bool(" + this.get$code() + ")");
  }
  else if (toType.get$library().get$isCore() && toType.get$typeofName() != null) {
    check = ("$assert_" + toType.name + "(" + this.get$code() + ")");
    if (toType.typeCheckCode == null) {
      toType.typeCheckCode = ("function $assert_" + toType.name + "(x) {\n  if (x == null || typeof(x) == \"" + toType.get$typeofName() + "\") return x;\n  " + throwTypeError("x") + "\n}");
    }
  }
  else {
    toType.isChecked = true;
    var checkName = $add$("assert$", toType.get$jsname());
    var temp = context.getTemp(this);
    check = ("(" + context.assignTemp(temp, this).get$code() + " == null ? null :");
    check = $add$(check, (" " + temp.get$code() + "." + checkName + "())"));
    if ($ne$(this, temp)) context.freeTemp(temp);
    $globals.world.objectType.varStubs.putIfAbsent(checkName, (function () {
      return new VarMethodStub(checkName, null, Arguments.get$EMPTY(), throwTypeError("this"));
    })
    );
  }
  ($0 = context.get$counters()).typeAsserts = $0.typeAsserts + (1);
  return new Value(toType, check, this.span);
}
Value.prototype.instanceOf = function(context, toType, span, isTrue, forceCheck) {
  if (toType.get$isVar()) {
    $globals.world.error("cannot resolve type", span);
  }
  var testCode = null;
  if (toType.get$isVar() || toType.get$isObject() || (toType instanceof ParameterType)) {
    if (this.get$needsTemp()) {
      return new Value($globals.world.nonNullBool, ("(" + this.get$code() + ", true)"), span);
    }
    else {
      return Value.fromBool(true, span);
    }
  }
  if (toType.get$library().get$isCore()) {
    var typeofName = toType.get$typeofName();
    if ($ne$(typeofName)) {
      testCode = ("(typeof(" + this.get$code() + ") " + (isTrue ? "==" : "!=") + " '" + typeofName + "')");
    }
  }
  if (toType.get$isClass() && !toType.get$isHiddenNativeType() && !toType.get$isConcreteGeneric()) {
    toType.markUsed();
    testCode = ("(" + this.get$code() + " instanceof " + toType.get$jsname() + ")");
    if (!isTrue) {
      testCode = $add$("!", testCode);
    }
  }
  if (testCode == null) {
    toType.isTested = true;
    var temp = context.getTemp(this);
    var checkName = ("is$" + toType.get$jsname());
    testCode = ("(" + context.assignTemp(temp, this).get$code() + " &&");
    testCode = $add$(testCode, (" " + temp.get$code() + "." + checkName + "())"));
    if (isTrue) {
      testCode = $add$("!!", testCode);
    }
    else {
      testCode = $add$("!", testCode);
    }
    if ($ne$(this, temp)) context.freeTemp(temp);
    if (!$globals.world.objectType.varStubs.containsKey(checkName)) {
      $globals.world.objectType.varStubs.$setindex(checkName, new VarMethodStub(checkName, null, Arguments.get$EMPTY(), "return false"));
    }
  }
  return new Value($globals.world.nonNullBool, testCode, span);
}
Value.prototype.convertWarning = function(toType) {
  $globals.world.warning(("type \"" + this.get$type().get$fullname() + "\" is not assignable to \"" + toType.get$fullname() + "\""), this.span);
}
Value.prototype.invokeNoSuchMethod = function(context, name, node, args) {
  if (this.get$isType()) {
    $globals.world.error(("member lookup failed for \"" + name + "\""), node.span);
  }
  var pos = "";
  if (args != null) {
    var argsCode = [];
    for (var i = (0);
     i < args.get$length(); i++) {
      argsCode.add(args.values.$index(i).get$code());
    }
    pos = Strings.join(argsCode, ", ");
  }
  var noSuchArgs = [new Value($globals.world.stringType, ("\"" + name + "\""), node.span), new Value($globals.world.listType, ("[" + pos + "]"), node.span)];
  return this._resolveMember(context, "noSuchMethod", node).invoke(context, node, this, new Arguments(null, noSuchArgs));
}
Value.fromBool = function(value, span) {
  return new BoolValue(value, true, span);
}
Value.fromInt = function(value, span) {
  return new IntValue(value, true, span);
}
Value.fromDouble = function(value, span) {
  return new DoubleValue(value, true, span);
}
Value.fromString = function(value, span) {
  return new StringValue(value, true, span);
}
Value.fromNull = function(span) {
  return new NullValue(true, span);
}
Value.prototype.instanceOf$3$isTrue$forceCheck = Value.prototype.instanceOf;
Value.prototype.instanceOf$4 = function($0, $1, $2, $3) {
  return this.instanceOf($0, $1, $2, $3, false);
};
Value.prototype.invokeNoSuchMethod$3 = Value.prototype.invokeNoSuchMethod;
Value.prototype.setIndex$4$kind = function($0, $1, $2, $3, kind) {
  return this.setIndex($0, $1, $2, $3, kind, (1));
};
Value.prototype.setIndex$4$kind$returnKind = Value.prototype.setIndex;
Value.prototype.set_$4$kind = function($0, $1, $2, $3, kind) {
  return this.set_($0, $1, $2, $3, kind, (1));
};
Value.prototype.set_$4$kind$returnKind = Value.prototype.set_;
// ********** Code for PureStaticValue **************
$inherits(PureStaticValue, Value);
function PureStaticValue(type, span, isConst, isType) {
  this.isType = isType;
  this.isConst = isConst;
  Value.call(this, type, null, span);
}
PureStaticValue.prototype.get$isConst = function() { return this.isConst; };
PureStaticValue.prototype.get$isType = function() { return this.isType; };
PureStaticValue.prototype.getMem = function(context, name, node) {
  var member = this.get$type().getMember(name);
  if ($eq$(member)) {
    $globals.world.warning(("cannot find \"" + name + "\" on \"" + this.get$type().name + "\""), node.span);
    return null;
  }
  if (this.isType && !member.get$isStatic()) {
    $globals.world.error("cannot refer to instance member as static", node.span);
  }
  return member;
}
PureStaticValue.prototype.get_ = function(context, name, node) {
  if (this.get$type().get$isVar()) return new PureStaticValue($globals.world.varType, node.span, false, false);
  var member = this.getMem(context, name, node);
  if ($eq$(member)) return new PureStaticValue($globals.world.varType, node.span, false, false);
  return member._get(context, node, this);
}
PureStaticValue.prototype.set_ = function(context, name, node, value, kind, returnKind) {
  if (this.get$type().get$isVar()) return new PureStaticValue($globals.world.varType, node.span, false, false);
  var member = this.getMem(context, name, node);
  if ($ne$(member)) {
    member._set(context, node, this, value);
  }
  return new PureStaticValue(value.get$type(), node.span, false, false);
}
PureStaticValue.prototype.setIndex = function(context, index, node, value, kind, returnKind) {
  var tmp = this.invoke(context, ":setindex", node, new Arguments(null, [index, value]));
  return new PureStaticValue(value.get$type(), node.span, false, false);
}
PureStaticValue.prototype.unop = function(kind, context, node) {
  switch (kind) {
    case (19):

      return new PureStaticValue($globals.world.boolType, node.get$span(), false, false);

    case (42):

      if (!this.isConst && !this.get$type().get$isNum()) {
        $globals.world.error("no unary add operator in dart", node.get$span());
      }
      return new PureStaticValue($globals.world.numType, node.get$span(), false, false);

    case (43):

      return this.invoke(context, ":negate", node, Arguments.get$EMPTY());

    case (18):

      return this.invoke(context, ":bit_not", node, Arguments.get$EMPTY());

  }
  $globals.world.internalError(("unimplemented: " + node.get$op()), node.get$span());
}
PureStaticValue.prototype.binop = function(kind, other, context, node) {
  var isConst = this.isConst && other.get$isConst();
  switch (kind) {
    case (35):
    case (34):

      return new PureStaticValue($globals.world.boolType, node.get$span(), isConst, false);

    case (50):

      return new PureStaticValue($globals.world.boolType, node.get$span(), isConst, false);

    case (51):

      return new PureStaticValue($globals.world.boolType, node.get$span(), isConst, false);

  }
  var name = kind == (49) ? ":ne" : TokenKind.binaryMethodName(kind);
  var ret = this.invoke(context, name, node, new Arguments(null, [other]));
  if (isConst) {
    ret = new PureStaticValue(ret.get$type(), node.get$span(), isConst, false);
  }
  return ret;
}
PureStaticValue.prototype.invoke = function(context, name, node, args) {
  if (this.get$type().get$isVar()) return new PureStaticValue($globals.world.varType, node.span, false, false);
  if (this.get$type().get$isFunction() && name == ":call") {
    return new PureStaticValue($globals.world.varType, node.span, false, false);
  }
  var member = this.getMem(context, name, node);
  if ($eq$(member)) return new PureStaticValue($globals.world.varType, node.span, false, false);
  return member.invoke(context, node, this, args);
}
PureStaticValue.prototype.invokeNoSuchMethod = function(context, name, node, args) {
  if (this.isType) {
    $globals.world.error(("member lookup failed for \"" + name + "\""), node.span);
  }
  var member = this.getMem(context, "noSuchMethod", node);
  if ($eq$(member)) return new PureStaticValue($globals.world.varType, node.span, false, false);
  var noSuchArgs = new Arguments(null, [new PureStaticValue($globals.world.stringType, node.span, false, false), new PureStaticValue($globals.world.listType, node.span, false, false)]);
  return member.invoke(context, node, this, noSuchArgs);
}
PureStaticValue.prototype._typeAssert = function(context, toType) {
  return this._changeStaticType(toType);
}
PureStaticValue.prototype._changeStaticType = function(toType) {
  if ((null == toType ? null == (this.get$type()) : toType === this.get$type())) return this;
  return new PureStaticValue(toType, this.span, this.isConst, this.isType);
}
PureStaticValue.prototype.invokeNoSuchMethod$3 = PureStaticValue.prototype.invokeNoSuchMethod;
PureStaticValue.prototype.setIndex$4$kind = function($0, $1, $2, $3, kind) {
  return this.setIndex($0, $1, $2, $3, kind, (1));
};
PureStaticValue.prototype.setIndex$4$kind$returnKind = PureStaticValue.prototype.setIndex;
PureStaticValue.prototype.set_$4$kind = function($0, $1, $2, $3, kind) {
  return this.set_($0, $1, $2, $3, kind, (1));
};
PureStaticValue.prototype.set_$4$kind$returnKind = PureStaticValue.prototype.set_;
// ********** Code for EvaluatedValue **************
$inherits(EvaluatedValue, Value);
function EvaluatedValue(isConst, type, span) {
  this.isConst = isConst;
  Value.call(this, type, "@@@", span);
}
EvaluatedValue.prototype.get$isConst = function() { return this.isConst; };
EvaluatedValue.prototype.get$code = function() {
  $globals.world.internalError("Should not be getting code from raw EvaluatedValue", this.span);
}
EvaluatedValue.prototype.get$needsTemp = function() {
  return false;
}
EvaluatedValue.prototype.hashCode = function() {
  return this.get$code().hashCode();
}
EvaluatedValue.prototype.$eq = function(other) {
  return (other instanceof EvaluatedValue) && $eq$(other.get$type(), this.get$type()) && $eq$(other.get$code(), this.get$code());
}
// ********** Code for NullValue **************
$inherits(NullValue, EvaluatedValue);
function NullValue(isConst, span) {
  EvaluatedValue.call(this, isConst, $globals.world.varType, span);
}
NullValue.prototype.get$actualValue = function() {
  return null;
}
NullValue.prototype.get$code = function() {
  return "null";
}
NullValue.prototype.binop = function(kind, other, context, node) {
  if (!(other instanceof NullValue)) return Value.prototype.binop.call(this, kind, other, context, node);
  var c = this.isConst && other.get$isConst();
  var s = node.get$span();
  switch (kind) {
    case (50):
    case (48):

      return new BoolValue(true, c, s);

    case (51):
    case (49):

      return new BoolValue(false, c, s);

  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for BoolValue **************
$inherits(BoolValue, EvaluatedValue);
function BoolValue(actualValue, isConst, span) {
  this.actualValue = actualValue;
  EvaluatedValue.call(this, isConst, $globals.world.nonNullBool, span);
}
BoolValue.prototype.get$actualValue = function() { return this.actualValue; };
BoolValue.prototype.get$code = function() {
  return this.actualValue ? "true" : "false";
}
BoolValue.prototype.unop = function(kind, context, node) {
  switch (kind) {
    case (19):

      return new BoolValue(!this.actualValue, this.isConst, node.get$span());

  }
  return Value.prototype.unop.call(this, kind, context, node);
}
BoolValue.prototype.binop = function(kind, other, context, node) {
  if (!(other instanceof BoolValue)) return Value.prototype.binop.call(this, kind, other, context, node);
  var c = this.isConst && other.get$isConst();
  var s = node.get$span();
  var x = this.actualValue, y = other.get$actualValue();
  switch (kind) {
    case (50):
    case (48):

      return new BoolValue($eq$(x, y), c, s);

    case (51):
    case (49):

      return new BoolValue($ne$(x, y), c, s);

    case (35):

      return new BoolValue(x && y, c, s);

    case (34):

      return new BoolValue(x || y, c, s);

  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for IntValue **************
$inherits(IntValue, EvaluatedValue);
function IntValue(actualValue, isConst, span) {
  this.actualValue = actualValue;
  EvaluatedValue.call(this, isConst, $globals.world.intType, span);
}
IntValue.prototype.get$actualValue = function() { return this.actualValue; };
IntValue.prototype.get$code = function() {
  return ("(" + this.actualValue + ")");
}
IntValue.prototype.unop = function(kind, context, node) {
  switch (kind) {
    case (42):

      return new IntValue(this.actualValue, this.isConst, this.span);

    case (43):

      return new IntValue(-this.actualValue, this.isConst, this.span);

    case (18):

      return new IntValue(~this.actualValue, this.isConst, this.span);

  }
  return Value.prototype.unop.call(this, kind, context, node);
}
IntValue.prototype.binop = function(kind, other, context, node) {
  var c = this.isConst && other.get$isConst();
  var s = node.get$span();
  if ((other instanceof IntValue)) {
    var x = this.actualValue;
    var y = other.get$actualValue();
    switch (kind) {
      case (50):
      case (48):

        return new BoolValue(x == y, c, s);

      case (51):
      case (49):

        return new BoolValue(x != y, c, s);

      case (36):

        return new IntValue(x | y, c, s);

      case (37):

        return new IntValue(x ^ y, c, s);

      case (38):

        return new IntValue(x & y, c, s);

      case (39):

        return new IntValue(x << y, c, s);

      case (40):

        return new IntValue(x >> y, c, s);

      case (42):

        return new IntValue(x + y, c, s);

      case (43):

        return new IntValue(x - y, c, s);

      case (44):

        return new IntValue(x * y, c, s);

      case (45):

        return new DoubleValue(x / y, c, s);

      case (46):

        return new IntValue($truncdiv$(x, y), c, s);

      case (47):

        return new IntValue($mod$(x, y), c, s);

      case (52):

        return new BoolValue(x < y, c, s);

      case (53):

        return new BoolValue(x > y, c, s);

      case (54):

        return new BoolValue(x <= y, c, s);

      case (55):

        return new BoolValue(x >= y, c, s);

    }
  }
  else if ((other instanceof DoubleValue)) {
    var x = this.actualValue;
    var y = other.get$actualValue();
    switch (kind) {
      case (50):
      case (48):

        return new BoolValue(x == y, c, s);

      case (51):
      case (49):

        return new BoolValue(x != y, c, s);

      case (42):

        return new DoubleValue(x + y, c, s);

      case (43):

        return new DoubleValue(x - y, c, s);

      case (44):

        return new DoubleValue(x * y, c, s);

      case (45):

        return new DoubleValue(x / y, c, s);

      case (46):

        return new DoubleValue($truncdiv$(x, y), c, s);

      case (47):

        return new DoubleValue($mod$(x, y), c, s);

      case (52):

        return new BoolValue(x < y, c, s);

      case (53):

        return new BoolValue(x > y, c, s);

      case (54):

        return new BoolValue(x <= y, c, s);

      case (55):

        return new BoolValue(x >= y, c, s);

    }
  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for DoubleValue **************
$inherits(DoubleValue, EvaluatedValue);
function DoubleValue(actualValue, isConst, span) {
  this.actualValue = actualValue;
  EvaluatedValue.call(this, isConst, $globals.world.doubleType, span);
}
DoubleValue.prototype.get$actualValue = function() { return this.actualValue; };
DoubleValue.prototype.get$code = function() {
  return ("(" + this.actualValue + ")");
}
DoubleValue.prototype.unop = function(kind, context, node) {
  switch (kind) {
    case (42):

      return new DoubleValue(this.actualValue, this.isConst, this.span);

    case (43):

      return new DoubleValue(-this.actualValue, this.isConst, this.span);

  }
  return Value.prototype.unop.call(this, kind, context, node);
}
DoubleValue.prototype.binop = function(kind, other, context, node) {
  var c = this.isConst && other.get$isConst();
  var s = node.get$span();
  if ((other instanceof DoubleValue)) {
    var x = this.actualValue;
    var y = other.get$actualValue();
    switch (kind) {
      case (50):
      case (48):

        return new BoolValue(x == y, c, s);

      case (51):
      case (49):

        return new BoolValue(x != y, c, s);

      case (42):

        return new DoubleValue(x + y, c, s);

      case (43):

        return new DoubleValue(x - y, c, s);

      case (44):

        return new DoubleValue(x * y, c, s);

      case (45):

        return new DoubleValue(x / y, c, s);

      case (46):

        return new DoubleValue($truncdiv$(x, y), c, s);

      case (47):

        return new DoubleValue($mod$(x, y), c, s);

      case (52):

        return new BoolValue(x < y, c, s);

      case (53):

        return new BoolValue(x > y, c, s);

      case (54):

        return new BoolValue(x <= y, c, s);

      case (55):

        return new BoolValue(x >= y, c, s);

    }
  }
  else if ((other instanceof IntValue)) {
    var x = this.actualValue;
    var y = other.get$actualValue();
    switch (kind) {
      case (50):
      case (48):

        return new BoolValue(x == y, c, s);

      case (51):
      case (49):

        return new BoolValue(x != y, c, s);

      case (42):

        return new DoubleValue(x + y, c, s);

      case (43):

        return new DoubleValue(x - y, c, s);

      case (44):

        return new DoubleValue(x * y, c, s);

      case (45):

        return new DoubleValue(x / y, c, s);

      case (46):

        return new DoubleValue($truncdiv$(x, y), c, s);

      case (47):

        return new DoubleValue($mod$(x, y), c, s);

      case (52):

        return new BoolValue(x < y, c, s);

      case (53):

        return new BoolValue(x > y, c, s);

      case (54):

        return new BoolValue(x <= y, c, s);

      case (55):

        return new BoolValue(x >= y, c, s);

    }
  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for StringValue **************
$inherits(StringValue, EvaluatedValue);
function StringValue(actualValue, isConst, span) {
  this.actualValue = actualValue;
  EvaluatedValue.call(this, isConst, $globals.world.stringType, span);
}
StringValue.prototype.get$actualValue = function() { return this.actualValue; };
StringValue.prototype.binop = function(kind, other, context, node) {
  if (!(other instanceof StringValue)) return Value.prototype.binop.call(this, kind, other, context, node);
  var c = this.isConst && other.get$isConst();
  var s = node.get$span();
  var x = this.actualValue, y = other.get$actualValue();
  switch (kind) {
    case (50):
    case (48):

      return new BoolValue(x == y, c, s);

    case (51):
    case (49):

      return new BoolValue(x != y, c, s);

    case (42):

      return new StringValue($add$(x, y), c, s);

  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
StringValue.prototype.get$code = function() {
  var buf = new StringBufferImpl("");
  buf.add("\"");
  for (var i = (0);
   i < this.actualValue.length; i++) {
    var ch = this.actualValue.charCodeAt(i);
    switch (ch) {
      case (9):

        buf.add("\\t");
        break;

      case (10):

        buf.add("\\n");
        break;

      case (13):

        buf.add("\\r");
        break;

      case (34):

        buf.add("\\\"");
        break;

      case (92):

        buf.add("\\\\");
        break;

      default:

        if ($gte$(ch, (32)) && $lte$(ch, (126))) {
          buf.add(this.actualValue[i]);
        }
        else {
          var hex = ch.toRadixString((16));
          switch (hex.get$length()) {
            case (1):

              buf.add("\\x0");
              buf.add(hex);
              break;

            case (2):

              buf.add("\\x");
              buf.add(hex);
              break;

            case (3):

              buf.add("\\u0");
              buf.add(hex);
              break;

            case (4):

              buf.add("\\u");
              buf.add(hex);
              break;

            default:

              $globals.world.internalError("unicode values greater than 2 bytes not implemented");
              break;

          }
        }
        break;

    }
  }
  buf.add("\"");
  return buf.toString();
}
// ********** Code for ListValue **************
$inherits(ListValue, EvaluatedValue);
function ListValue(values, isConst, type, span) {
  this.values = values;
  EvaluatedValue.call(this, isConst, type, span);
}
ListValue.prototype.get$code = function() {
  var buf = new StringBufferImpl("");
  buf.add("[");
  for (var i = (0);
   $lt$(i, this.values.get$length()); i = $add$(i, (1))) {
    if ($gt$(i, (0))) buf.add(", ");
    buf.add(this.values.$index(i).get$code());
  }
  buf.add("]");
  var listCode = buf.toString$0();
  if (!this.isConst) return listCode;
  var v = new Value($globals.world.listType, listCode, this.span);
  var immutableListCtor = $globals.world.immutableListType.getConstructor("from");
  var result = immutableListCtor.invoke($globals.world.gen.mainContext, null, new TypeValue(v.get$type(), this.span), new Arguments(null, [v]));
  return result.get$code();
}
ListValue.prototype.binop = function(kind, other, context, node) {
  if (!(other instanceof ListValue)) return Value.prototype.binop.call(this, kind, other, context, node);
  switch (kind) {
    case (50):

      return new BoolValue($eq$(this.get$type(), other.get$type()) && this.get$code() == other.get$code(), this.isConst && other.get$isConst(), node.get$span());

    case (51):

      return new BoolValue($ne$(this.get$type(), other.get$type()) || this.get$code() != other.get$code(), this.isConst && other.get$isConst(), node.get$span());

  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
ListValue.prototype.getGlobalValue = function() {
  return $globals.world.gen.globalForConst(this, this.values);
}
// ********** Code for MapValue **************
$inherits(MapValue, EvaluatedValue);
function MapValue(values, isConst, type, span) {
  this.values = values;
  EvaluatedValue.call(this, isConst, type, span);
}
MapValue.prototype.get$code = function() {
  var items = new ListValue(this.values, false, $globals.world.listType, this.span);
  var tp = $globals.world.coreimpl.topType;
  var f = this.isConst ? tp.getMember("_constMap") : tp.getMember("_map");
  var value = f.invoke($globals.world.gen.mainContext, null, new TypeValue(tp, null), new Arguments(null, [items]));
  return value.get$code();
}
MapValue.prototype.getGlobalValue = function() {
  return $globals.world.gen.globalForConst(this, this.values);
}
MapValue.prototype.binop = function(kind, other, context, node) {
  if (!(other instanceof MapValue)) return Value.prototype.binop.call(this, kind, other, context, node);
  switch (kind) {
    case (50):

      return new BoolValue($eq$(this.get$type(), other.get$type()) && this.get$code() == other.get$code(), this.isConst && other.get$isConst(), node.get$span());

    case (51):

      return new BoolValue($ne$(this.get$type(), other.get$type()) || this.get$code() != other.get$code(), this.isConst && other.get$isConst(), node.get$span());

  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for ObjectValue **************
$inherits(ObjectValue, EvaluatedValue);
function ObjectValue(isConst, type, span) {
  this.seenNativeInitializer = false;
  this.fields = new HashMapImplementation();
  EvaluatedValue.call(this, isConst, type, span);
}
ObjectValue.prototype.get$fields = function() { return this.fields; };
ObjectValue.prototype.get$seenNativeInitializer = function() { return this.seenNativeInitializer; };
ObjectValue.prototype.set$seenNativeInitializer = function(value) { return this.seenNativeInitializer = value; };
ObjectValue.prototype.get$code = function() {
  if (null == this._code) this.validateInitialized(null);
  return this._code;
}
ObjectValue.prototype.initFields = function() {
  var allMembers = $globals.world.gen._orderValues(this.get$type().get$genericType().getAllMembers());
  for (var $$i = allMembers.iterator(); $$i.hasNext(); ) {
    var f = $$i.next();
    if (f.get$isField() && !f.get$isStatic() && f.get$declaringType().get$isClass()) {
      this.fields.$setindex(f, f.computeValue());
    }
  }
}
ObjectValue.prototype.setField = function(field, value, duringInit) {
  if (value.get$isConst() && (value instanceof VariableValue)) {
    value = value.get$dynamic().get$value();
  }
  var currentValue = this.fields.$index(field);
  if (this.isConst && !value.get$isConst()) {
    $globals.world.error("used of non-const value in const intializer", value.span);
  }
  if (null == currentValue) {
    this.fields.$setindex(field, value);
    if (field.get$isFinal() && !duringInit) {
      $globals.world.error("cannot initialize final fields outside of initializer", value.span);
    }
  }
  else {
    if (field.get$isFinal() && null == field.computeValue()) {
      $globals.world.error("reassignment of field not allowed", value.span, field.get$span());
    }
    else {
      this.fields.$setindex(field, value);
    }
  }
}
ObjectValue.prototype.validateInitialized = function(span) {
  var buf = new StringBufferImpl("");
  buf.add("Object.create(");
  buf.add(("" + this.get$type().get$jsname() + ".prototype, "));
  buf.add("{");
  var addComma = false;
  var $$list = this.fields.getKeys();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var field = $$i.next();
    if (addComma) buf.add(", ");
    buf.add(field.get$name());
    buf.add(": ");
    buf.add("{\"value\": ");
    if (null == this.fields.$index(field)) {
      $globals.world.error(("Required field \"" + field.get$name() + "\" was not initialized"), span, field.get$span());
      buf.add("null");
    }
    else {
      buf.add(this.fields.$index(field).get$code());
    }
    buf.add(", writeable: false}");
    addComma = true;
  }
  buf.add("})");
  this._code = buf.toString$0();
}
ObjectValue.prototype.binop = function(kind, other, context, node) {
  if (!(other instanceof ObjectValue)) return Value.prototype.binop.call(this, kind, other, context, node);
  switch (kind) {
    case (50):
    case (48):

      return new BoolValue($eq$(this.get$type(), other.get$type()) && this.get$code() == other.get$code(), this.isConst && other.get$isConst(), node.get$span());

    case (51):
    case (49):

      return new BoolValue($ne$(this.get$type(), other.get$type()) || this.get$code() != other.get$code(), this.isConst && other.get$isConst(), node.get$span());

  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for GlobalValue **************
$inherits(GlobalValue, Value);
function GlobalValue(type, code, isConst, field, name, exp, span, deps) {
  this.exp = exp;
  this.field = field;
  this.name = name;
  this.dependencies = [];
  this.isConst = isConst;
  Value.call(this, type, code, span);
  for (var $$i = deps.iterator(); $$i.hasNext(); ) {
    var dep = $$i.next();
    if ((dep instanceof GlobalValue)) {
      this.dependencies.add(dep);
      this.dependencies.addAll(dep.get$dependencies());
    }
  }
}
GlobalValue.prototype.get$field = function() { return this.field; };
GlobalValue.prototype.get$name = function() { return this.name; };
GlobalValue.prototype.get$exp = function() { return this.exp; };
GlobalValue.prototype.get$isConst = function() { return this.isConst; };
GlobalValue.prototype.get$actualValue = function() {
  return this.exp.get$dynamic().get$actualValue();
}
GlobalValue.prototype.get$dependencies = function() { return this.dependencies; };
GlobalValue.prototype.get$needsTemp = function() {
  return !this.isConst;
}
GlobalValue.prototype.compareTo = function(other) {
  if ($eq$(other, this)) {
    return (0);
  }
  else if (this.dependencies.indexOf(other) >= (0)) {
    return (1);
  }
  else if (other.dependencies.indexOf(this) >= (0)) {
    return (-1);
  }
  else if (this.dependencies.get$length() > other.dependencies.get$length()) {
    return (1);
  }
  else if (this.dependencies.get$length() < other.dependencies.get$length()) {
    return (-1);
  }
  else if (this.name == null && other.name != null) {
    return (1);
  }
  else if (this.name != null && other.name == null) {
    return (-1);
  }
  else if (this.name != null) {
    return this.name.compareTo(other.name);
  }
  else {
    return this.field.name.compareTo(other.field.name);
  }
}
// ********** Code for BareValue **************
$inherits(BareValue, Value);
function BareValue(home, outermost, span) {
  this.isType = outermost.get$isStatic();
  this.home = home;
  Value.call(this, outermost.method.get$declaringType(), null, span);
}
BareValue.prototype.get$isType = function() { return this.isType; };
BareValue.prototype.get$needsTemp = function() {
  return false;
}
BareValue.prototype._shouldBindDynamically = function() {
  return false;
}
BareValue.prototype.get$code = function() {
  return this._code;
}
BareValue.prototype._ensureCode = function() {
  if (null == this._code) this._code = this.isType ? this.get$type().get$jsname() : this.home._makeThisCode();
}
BareValue.prototype._tryResolveMember = function(context, name, node) {
  var member = this.get$type().getMember(name);
  if ($eq$(member) || $ne$(member.get$declaringType(), this.get$type())) {
    var libMember = this.home.get$library().lookup(name, this.span);
    if (null != libMember) {
      return libMember.get$preciseMemberSet();
    }
  }
  this._ensureCode();
  return Value.prototype._tryResolveMember.call(this, context, name, node);
}
// ********** Code for SuperValue **************
$inherits(SuperValue, Value);
function SuperValue(parentType, span) {
  Value.call(this, parentType, "this", span);
}
SuperValue.prototype.get$needsTemp = function() {
  return false;
}
SuperValue.prototype.get$isSuper = function() {
  return true;
}
SuperValue.prototype._shouldBindDynamically = function() {
  return false;
}
SuperValue.prototype._tryUnion = function(right) {
  return (right instanceof SuperValue) ? this : null;
}
// ********** Code for ThisValue **************
$inherits(ThisValue, Value);
function ThisValue(type, code, span) {
  Value.call(this, type, code, span);
}
ThisValue.prototype.get$needsTemp = function() {
  return false;
}
ThisValue.prototype._shouldBindDynamically = function() {
  return false;
}
ThisValue.prototype._tryUnion = function(right) {
  return (right instanceof ThisValue) ? this : null;
}
// ********** Code for TypeValue **************
$inherits(TypeValue, Value);
function TypeValue(type, span) {
  Value.call(this, type, null, span);
}
TypeValue.prototype.get$needsTemp = function() {
  return false;
}
TypeValue.prototype.get$isType = function() {
  return true;
}
TypeValue.prototype._shouldBindDynamically = function() {
  return false;
}
TypeValue.prototype._tryUnion = function(right) {
  return (right instanceof TypeValue) ? this : null;
}
// ********** Code for VariableValue **************
$inherits(VariableValue, Value);
function VariableValue(staticType, code, span, isFinal, value) {
  this.value = VariableValue._unwrap(value);
  this.isFinal = isFinal;
  Value.call(this, staticType, code, span);
}
VariableValue.prototype.get$isFinal = function() { return this.isFinal; };
VariableValue.prototype.get$value = function() { return this.value; };
VariableValue._unwrap = function(v) {
  if (null == v) return null;
  if ((v instanceof VariableValue)) {
    v = v.get$dynamic().get$value();
  }
  return v;
}
VariableValue.prototype._tryUnion = function(right) {
  return Value.union(this.value, right);
}
VariableValue.prototype.get$needsTemp = function() {
  return false;
}
VariableValue.prototype.get$type = function() {
  return null != this.value ? this.value.get$type() : this.get$staticType();
}
VariableValue.prototype.get$staticType = function() {
  return this.type;
}
VariableValue.prototype.get$isConst = function() {
  return null != this.value ? this.value.get$isConst() : false;
}
VariableValue.prototype.replaceValue = function(v) {
  return new VariableValue(this.get$staticType(), this.get$code(), this.span, this.isFinal, v);
}
VariableValue.prototype.unop = function(kind, context, node) {
  if (this.value != null) {
    return this.replaceValue(this.value.unop(kind, context, node));
  }
  return Value.prototype.unop.call(this, kind, context, node);
}
VariableValue.prototype.binop = function(kind, other, context, node) {
  if (this.value != null) {
    return this.replaceValue(this.value.binop(kind, VariableValue._unwrap(other), context, node));
  }
  return Value.prototype.binop.call(this, kind, other, context, node);
}
// ********** Code for CompilerException **************
function CompilerException(_message, _location) {
  this._lang_message = _message;
  this._location = _location;
}
CompilerException.prototype.toString = function() {
  if (this._location != null) {
    return ("CompilerException: " + this._location.toMessageString(this._lang_message));
  }
  else {
    return ("CompilerException: " + this._lang_message);
  }
}
CompilerException.prototype.toString$0 = CompilerException.prototype.toString;
// ********** Code for CounterLog **************
function CounterLog() {
  this.msetN = (0);
  this.objectProtoMembers = (0);
  this.dynamicMethodCalls = (0);
  this.typeAsserts = (0);
  this.invokeCalls = (0);
}
CounterLog.prototype.info = function() {
  if ($globals.options.legOnly) return;
  $globals.world.info(("Dynamically typed method calls: " + this.dynamicMethodCalls));
  $globals.world.info(("Generated type assertions: " + this.typeAsserts));
  $globals.world.info(("Members on Object.prototype: " + this.objectProtoMembers));
  $globals.world.info(("Invoke calls: " + this.invokeCalls));
  $globals.world.info(("msetN calls: " + this.msetN));
}
CounterLog.prototype.add = function(other) {
  this.dynamicMethodCalls = this.dynamicMethodCalls + other.dynamicMethodCalls;
  this.typeAsserts = this.typeAsserts + other.typeAsserts;
  this.objectProtoMembers = this.objectProtoMembers + other.objectProtoMembers;
  this.invokeCalls = this.invokeCalls + other.invokeCalls;
  this.msetN = this.msetN + other.msetN;
}
// ********** Code for World **************
function World(files) {
  this.files = files;
  this._members = new HashMapImplementation();
  this._topNames = new HashMapImplementation();
  this.warnings = (0);
  this.seenFatal = false;
  this.libraries = new HashMapImplementation();
  this.dartBytesRead = (0);
  this._todo = [];
  this.jsBytesWritten = (0);
  this.counters = new CounterLog();
  this.errors = (0);
  this.reader = new LibraryReader();
}
World.prototype.get$functionType = function() { return this.functionType; };
World.prototype.init = function() {
  this.corelib = new Library(this.readFile("dart:core"));
  this.libraries.$setindex("dart:core", this.corelib);
  this._todo.add(this.corelib);
  this.coreimpl = this.getOrAddLibrary("dart:coreimpl");
  this.voidType = this.corelib.addType("void", null, false);
  this.dynamicType = this.corelib.addType("Dynamic", null, false);
  this.varType = this.dynamicType;
  this.objectType = this.corelib.addType("Object", null, true);
  this.numType = this.corelib.addType("num", null, false);
  this.intType = this.corelib.addType("int", null, false);
  this.doubleType = this.corelib.addType("double", null, false);
  this.boolType = this.corelib.addType("bool", null, false);
  this.stringType = this.corelib.addType("String", null, false);
  this.listType = this.corelib.addType("List", null, false);
  this.mapType = this.corelib.addType("Map", null, false);
  this.functionType = this.corelib.addType("Function", null, false);
  this.typeErrorType = this.corelib.addType("TypeError", null, true);
  this.numImplType = this.coreimpl.addType("NumImplementation", null, true);
  this.stringImplType = this.coreimpl.addType("StringImplementation", null, true);
  this.immutableListType = this.coreimpl.addType("ImmutableList", null, true);
  this.listFactoryType = this.coreimpl.addType("ListFactory", null, true);
  this.functionImplType = this.coreimpl.addType("_FunctionImplementation", null, true);
  this.nonNullBool = new NonNullableType(this.boolType);
}
World.prototype._addMember = function(member) {
  if (member.get$isStatic()) {
    if (member.declaringType.get$isTop()) {
      this._addTopName(member);
    }
    return;
  }
  var mset = this._members.$index(member.name);
  if ($eq$(mset)) {
    mset = new MemberSet(member, true);
    this._members.$setindex(mset.get$name(), mset);
  }
  else {
    mset.get$members().add(member);
  }
}
World.prototype._addTopName = function(named) {
  if ((named instanceof Type) && named.get$isNative()) {
    if (named.get$avoidNativeName()) {
      this._addJavascriptTopName(new ExistingJsGlobal(named.get$nativeName(), named), named.get$nativeName());
    }
    else {
      this._addJavascriptTopName(named, named.get$nativeName());
    }
  }
  this._addJavascriptTopName(named, named.get$jsname());
}
World.prototype._addJavascriptTopName = function(named, name) {
  var existing = this._topNames.$index(name);
  if ($eq$(existing)) {
    this._topNames.$setindex(name, named);
    return;
  }
  if ((null == existing ? null == (named) : existing === named)) {
    return;
  }
  this.info($add$(("mangling matching top level name \"" + named.get$jsname() + "\" in "), ("both \"" + named.get$library().get$jsname() + "\" and \"" + existing.get$library().get$jsname() + "\"")));
  var existingPri = existing.get$jsnamePriority();
  var namedPri = named.get$jsnamePriority();
  if (existingPri > namedPri || namedPri == (0)) {
    this._renameJavascriptTopName(named);
  }
  else if (namedPri > existingPri) {
    this._renameJavascriptTopName(existing);
  }
  else {
    if (named.get$isNative()) {
      var msg = $add$($add$(("conflicting JS name \"" + name + "\" of same "), ("priority " + existingPri + ": (already defined in) ")), ("" + existing.get$span().get$locationText() + " with priority " + namedPri + ")"));
      $globals.world.info(msg, named.get$span(), existing.get$span());
    }
    else {
      this._renameJavascriptTopName(existing);
    }
  }
}
World.prototype._renameJavascriptTopName = function(named) {
  named._jsname = ("" + named.get$library().get$jsname() + "_" + named.get$jsname());
  var existing = this._topNames.$index(named.get$jsname());
  if ($ne$(existing) && $ne$(existing, named)) {
    $globals.world.internalError($add$(("name mangling failed for \"" + named.get$jsname() + "\" "), ("(\"" + named.get$jsname() + "\" defined also in " + existing.get$span().get$locationText() + ")")), named.get$span());
  }
  this._topNames.$setindex(named.get$jsname(), named);
}
World.prototype._addType = function(type) {
  if (!type.get$isTop()) this._addTopName(type);
}
World.prototype.toJsIdentifier = function(name) {
  if (name == null) return null;
  if (this._jsKeywords == null) {
    this._jsKeywords = HashSetImplementation.HashSetImplementation$from$factory(["break", "case", "catch", "continue", "debugger", "default", "delete", "do", "else", "finally", "for", "function", "if", "in", "instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with", "class", "enum", "export", "extends", "import", "super", "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "native"]);
  }
  if (this._jsKeywords.contains(name)) {
    return $add$(name, "_");
  }
  else {
    return name.replaceAll("$", "$$").replaceAll(":", "$");
  }
}
World.prototype.compileAndSave = function() {
  var success = this.compile();
  if ($globals.options.outfile != null) {
    if (success) {
      var code = $globals.world.getGeneratedCode();
      if (!$globals.options.outfile.endsWith(".js")) {
        code = $add$("#!/usr/bin/env node\n", code);
      }
      $globals.world.files.writeString($globals.options.outfile, code);
    }
    else {
      $globals.world.files.writeString($globals.options.outfile, "throw 'Sorry, but I could not generate reasonable code to run.\\n';");
    }
  }
  return success;
}
World.prototype.compile = function() {
  if ($globals.options.dartScript == null) {
    this.fatal("no script provided to compile");
    return false;
  }
  try {
    if ($globals.options.legOnly) {
      this.info(("[leg] compiling " + $globals.options.dartScript));
    }
    else {
      this.info(("compiling " + $globals.options.dartScript + " with corelib " + this.corelib));
    }
    if (!this.runLeg()) this.runCompilationPhases();
  } catch (exc) {
    exc = _toDartException(exc);
    if (this.get$hasErrors() && !$globals.options.throwOnErrors) {
    }
    else {
      throw exc;
    }
  }
  this.printStatus();
  return !this.get$hasErrors();
}
World.prototype.runLeg = function() {
  var $this = this; // closure support
  if (!$globals.options.legOnly) return false;
  if ($globals.legCompile == null) {
    this.fatal("requested leg enabled, but no leg compiler available");
  }
  var res = this.withTiming("[leg] compile", (function () {
    return $globals.legCompile($this);
  })
  );
  if (!res && $globals.options.legOnly) {
    this.fatal(("Leg could not compile " + $globals.options.dartScript));
    return true;
  }
  return res;
}
World.prototype.runCompilationPhases = function() {
  var $this = this; // closure support
  var lib = this.withTiming("first pass", (function () {
    return $this.processDartScript();
  })
  );
  this.withTiming("resolve top level", this.get$resolveAll());
  if ($globals.experimentalAwaitPhase != null) {
    this.withTiming("await translation", to$call$0($globals.experimentalAwaitPhase));
  }
  this.withTiming("analyze pass", (function () {
    $this.analyzeCode(lib);
  })
  );
  if ($globals.options.checkOnly) return;
  this.withTiming("generate code", (function () {
    $this.generateCode(lib);
  })
  );
}
World.prototype.getGeneratedCode = function() {
  if (this.legCode != null) {
    return this.legCode;
  }
  else {
    return this.frogCode;
  }
}
World.prototype.readFile = function(filename) {
  try {
    var sourceFile = this.reader.readFile(filename);
    this.dartBytesRead = this.dartBytesRead + sourceFile.get$text().length;
    return sourceFile;
  } catch (e) {
    e = _toDartException(e);
    this.warning(("Error reading file: " + filename));
    return new SourceFile(filename, "");
  }
}
World.prototype.getOrAddLibrary = function(filename) {
  var library = this.libraries.$index(filename);
  if (library == null) {
    library = new Library(this.readFile(filename));
    this.info(("read library " + filename));
    if (!library.get$isCore() && !library.imports.some((function (li) {
      return li.get$library().get$isCore();
    })
    )) {
      library.imports.add(new LibraryImport(this.corelib));
    }
    this.libraries.$setindex(filename, library);
    this._todo.add(library);
    if (filename == "dart:dom") {
      this.dom = library;
    }
    else if (filename == "dart:isolate") {
      this.isolatelib = library;
    }
  }
  return library;
}
World.prototype.process = function() {
  while (this._todo.get$length() > (0)) {
    var todo = this._todo;
    this._todo = [];
    for (var $$i = todo.iterator(); $$i.hasNext(); ) {
      var lib = $$i.next();
      lib.visitSources();
    }
  }
}
World.prototype.processDartScript = function(script) {
  if (script == null) script = $globals.options.dartScript;
  var library = this.getOrAddLibrary(script);
  this.process();
  return library;
}
World.prototype.resolveAll = function() {
  var $$list = this.libraries.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var lib = $$i.next();
    lib.resolve();
  }
  var $$list = this.libraries.getValues();
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var lib = $$i.next();
    lib.postResolveChecks();
  }
}
World.prototype.get$resolveAll = function() {
  return this.resolveAll.bind(this);
}
World.prototype.findMainMethod = function(lib) {
  var main = lib.lookup("main", lib.get$span());
  if ($eq$(main)) {
    if (!$globals.options.checkOnly) this.fatal("no main method specified");
  }
  return main;
}
World.prototype.analyzeCode = function(lib) {
  this.gen = new WorldGenerator(this.findMainMethod(lib), new CodeWriter());
  this.gen.analyze();
}
World.prototype.generateCode = function(lib) {
  this.gen.run();
  this.frogCode = this.gen.writer.get$text();
  this.jsBytesWritten = this.frogCode.length;
  this.gen = null;
}
World.prototype._message = function(color, prefix, message, span, span1, span2, throwing) {
  if (this.messageHandler != null) {
    this.messageHandler(prefix, message, span);
    if (span1 != null) {
      this.messageHandler(prefix, message, span1);
    }
    if (span2 != null) {
      this.messageHandler(prefix, message, span2);
    }
  }
  else {
    var messageWithPrefix = $globals.options.useColors ? ($add$($add$($add$(color, prefix), $globals._NO_COLOR), message)) : ($add$(prefix, message));
    var text = messageWithPrefix;
    if (span != null) {
      text = span.toMessageString(messageWithPrefix);
    }
    print$(text);
    if (span1 != null) {
      print$(span1.toMessageString(messageWithPrefix));
    }
    if (span2 != null) {
      print$(span2.toMessageString(messageWithPrefix));
    }
  }
  if (throwing) {
    $throw(new CompilerException($add$(prefix, message), span));
  }
}
World.prototype.error = function(message, span, span1, span2) {
  this.errors++;
  this._message($globals._RED_COLOR, "error: ", message, span, span1, span2, $globals.options.throwOnErrors);
}
World.prototype.warning = function(message, span, span1, span2) {
  if ($globals.options.warningsAsErrors) {
    this.error(message, span, span1, span2);
    return;
  }
  this.warnings++;
  if ($globals.options.showWarnings) {
    this._message($globals._MAGENTA_COLOR, "warning: ", message, span, span1, span2, $globals.options.throwOnWarnings);
  }
}
World.prototype.fatal = function(message, span, span1, span2) {
  this.errors++;
  this.seenFatal = true;
  this._message($globals._RED_COLOR, "fatal: ", message, span, span1, span2, $globals.options.throwOnFatal || $globals.options.throwOnErrors);
}
World.prototype.internalError = function(message, span, span1, span2) {
  this._message($globals._NO_COLOR, "We are sorry, but...", message, span, span1, span2, true);
}
World.prototype.info = function(message, span, span1, span2) {
  if ($globals.options.showInfo) {
    this._message($globals._GREEN_COLOR, "info: ", message, span, span1, span2, false);
  }
}
World.prototype.withoutForceDynamic = function(fn) {
  var oldForceDynamic = $globals.options.forceDynamic;
  $globals.options.forceDynamic = false;
  try {
    return fn();
  } finally {
    $globals.options.forceDynamic = oldForceDynamic;
  }
}
World.prototype.get$hasErrors = function() {
  return this.errors > (0);
}
World.prototype.printStatus = function() {
  this.counters.info();
  this.info(("compiled " + this.dartBytesRead + " bytes Dart -> " + this.jsBytesWritten + " bytes JS"));
  if (this.get$hasErrors()) {
    print$(("compilation failed with " + this.errors + " errors"));
  }
  else {
    if (this.warnings > (0)) {
      this.info(("compilation completed successfully with " + this.warnings + " warnings"));
    }
    else {
      this.info("compilation completed sucessfully");
    }
  }
}
World.prototype.withTiming = function(name, f) {
  var sw = new StopwatchImplementation();
  sw.start();
  var result = f();
  sw.stop();
  this.info(("" + name + " in " + sw.elapsedInMs() + "msec"));
  return result;
}
// ********** Code for FrogOptions **************
function FrogOptions(homedir, args, files) {
  this.legOnly = false;
  this.checkOnly = false;
  this.disableBoundsChecks = false;
  this.maxInferenceIterations = (4);
  this.throwOnWarnings = false;
  this.inferTypes = false;
  this.warningsAsErrors = false;
  this.enableAsserts = false;
  this.forceDynamic = false;
  this.dietParse = false;
  this.compileOnly = false;
  this.showWarnings = true;
  this.throwOnFatal = false;
  this.config = "dev";
  this.verifyImplements = false;
  this.enableTypeChecks = false;
  this.showInfo = false;
  this.useColors = true;
  this.compileAll = false;
  this.throwOnErrors = false;
  if ($eq$(this.config, "dev")) {
    this.libDir = joinPaths(homedir, "/lib");
  }
  else if ($eq$(this.config, "sdk")) {
    this.libDir = joinPaths(homedir, "/../lib");
  }
  else {
    $globals.world.error(("Invalid configuration " + this.config));
    $throw("Invalid configuration");
  }
  var ignoreUnrecognizedFlags = false;
  var passedLibDir = false;
  this.childArgs = [];
  loop:
  for (var i = (2);
   i < args.get$length(); i++) {
    var arg = args.$index(i);
    switch (arg) {
      case "--leg":
      case "--enable_leg":
      case "--leg_only":

        this.legOnly = true;
        break;

      case "--enable_asserts":

        this.enableAsserts = true;
        break;

      case "--enable_type_checks":

        this.enableTypeChecks = true;
        this.enableAsserts = true;
        break;

      case "--verify_implements":

        this.verifyImplements = true;
        break;

      case "--compile_all":

        this.compileAll = true;
        break;

      case "--check-only":

        this.checkOnly = true;
        break;

      case "--diet-parse":

        this.dietParse = true;
        break;

      case "--ignore-unrecognized-flags":

        ignoreUnrecognizedFlags = true;
        break;

      case "--verbose":

        this.showInfo = true;
        break;

      case "--suppress_warnings":

        this.showWarnings = false;
        break;

      case "--warnings_as_errors":

        this.warningsAsErrors = true;
        break;

      case "--throw_on_errors":

        this.throwOnErrors = true;
        break;

      case "--throw_on_warnings":

        this.throwOnWarnings = true;
        break;

      case "--compile-only":

        this.compileOnly = true;
        break;

      case "--Xforce_dynamic":

        this.forceDynamic = true;
        break;

      case "--no_colors":

        this.useColors = false;
        break;

      case "--Xinfer_types":

        this.inferTypes = true;
        break;

      case "--checked":

        this.enableTypeChecks = true;
        this.enableAsserts = true;
        break;

      case "--unchecked":

        this.disableBoundsChecks = true;
        break;

      default:

        if (arg.endsWith(".dart")) {
          this.dartScript = arg;
          this.childArgs = args.getRange(i + (1), args.get$length() - i - (1));
          break loop;
        }
        else if (arg.startsWith("--out=")) {
          this.outfile = arg.substring$1("--out=".length);
        }
        else if (arg.startsWith("--libdir=")) {
          this.libDir = arg.substring$1("--libdir=".length);
          passedLibDir = true;
        }
        else {
          if (!ignoreUnrecognizedFlags) {
            print$(("unrecognized flag: \"" + arg + "\""));
          }
        }

    }
  }
  if (!passedLibDir && $eq$(this.config, "dev") && !files.fileExists(this.libDir)) {
    var temp = "frog/lib";
    if (files.fileExists(temp)) {
      this.libDir = temp;
    }
    else {
      this.libDir = "lib";
    }
  }
}
// ********** Code for LibraryReader **************
function LibraryReader() {
  if ($eq$($globals.options.config, "dev")) {
    this._specialLibs = _map(["dart:core", joinPaths($globals.options.libDir, "corelib.dart"), "dart:coreimpl", joinPaths($globals.options.libDir, "corelib_impl.dart"), "dart:html", joinPaths($globals.options.libDir, "../../client/html/release/html.dart"), "dart:htmlimpl", joinPaths($globals.options.libDir, "../../client/html/release/htmlimpl.dart"), "dart:dom", joinPaths($globals.options.libDir, "../../client/dom/frog/dom_frog.dart"), "dart:json", joinPaths($globals.options.libDir, "../../lib/json/json_frog.dart"), "dart:isolate", joinPaths($globals.options.libDir, "../../lib/isolate/isolate_frog.dart")]);
  }
  else if ($eq$($globals.options.config, "sdk")) {
    this._specialLibs = _map(["dart:core", joinPaths($globals.options.libDir, "core/core_frog.dart"), "dart:coreimpl", joinPaths($globals.options.libDir, "coreimpl/coreimpl_frog.dart"), "dart:html", joinPaths($globals.options.libDir, "html/html.dart"), "dart:htmlimpl", joinPaths($globals.options.libDir, "htmlimpl/htmlimpl.dart"), "dart:dom", joinPaths($globals.options.libDir, "dom/frog/dom_frog.dart"), "dart:json", joinPaths($globals.options.libDir, "json/json_frog.dart"), "dart:isolate", joinPaths($globals.options.libDir, "isolate/isolate_frog.dart")]);
  }
  else {
    $globals.world.error(("Invalid configuration " + $globals.options.config));
  }
}
LibraryReader.prototype.readFile = function(fullname) {
  var filename = this._specialLibs.$index(fullname);
  if ($eq$(filename)) {
    filename = fullname;
  }
  if ($globals.world.files.fileExists(filename)) {
    return new SourceFile(filename, $globals.world.files.readAll(filename));
  }
  else {
    $globals.world.error(("File not found: " + filename));
    return new SourceFile(filename, "");
  }
}
// ********** Code for VarMember **************
function VarMember(name) {
  this.isGenerated = false;
  this.name = name;
}
VarMember.prototype.get$name = function() { return this.name; };
VarMember.prototype.get$isGenerated = function() { return this.isGenerated; };
VarMember.prototype.get$body = function() {
  return null;
}
VarMember.prototype.get$returnType = function() {
  return $globals.world.varType;
}
VarMember.prototype.invoke = function(context, node, target, args) {
  return new Value(this.get$returnType(), ("" + target.get$code() + "." + this.name + "(" + args.getCode() + ")"), node.span);
}
// ********** Code for VarFunctionStub **************
$inherits(VarFunctionStub, VarMember);
function VarFunctionStub(name, callArgs) {
  this.args = callArgs.toCallStubArgs();
  VarMember.call(this, name);
  $globals.world.functionImplType.markUsed();
  $globals.world.gen.genMethod($globals.world.functionImplType.getMember("_genStub"));
}
VarFunctionStub.prototype.invoke = function(context, node, target, args) {
  return VarMember.prototype.invoke.call(this, context, node, target, args);
}
VarFunctionStub.prototype.generate = function(code) {
  this.isGenerated = true;
  if (this.args.get$hasNames()) {
    this.generateNamed(code);
  }
  else {
    this.generatePositional(code);
  }
}
VarFunctionStub.prototype.generatePositional = function(w) {
  var arity = this.args.get$length();
  w.enterBlock(("Function.prototype.to$" + this.name + " = function() {"));
  w.writeln(("this." + this.name + " = this._genStub(" + arity + ");"));
  w.writeln(("this.to$" + this.name + " = function() { return this." + this.name + "; };"));
  w.writeln(("return this." + this.name + ";"));
  w.exitBlock("};");
  var argsCode = this.args.getCode();
  w.enterBlock(("Function.prototype." + this.name + " = function(" + argsCode + ") {"));
  w.writeln(("return this.to$" + this.name + "()(" + argsCode + ");"));
  w.exitBlock("};");
  w.writeln(("function to$" + this.name + "(f) { return f && f.to$" + this.name + "(); }"));
}
VarFunctionStub.prototype.generateNamed = function(w) {
  var named = Strings.join(this.args.getNames(), "\", \"");
  var argsCode = this.args.getCode();
  w.enterBlock(("Function.prototype." + this.name + " = function(" + argsCode + ") {"));
  w.writeln(("this." + this.name + " = this._genStub(" + this.args.get$length() + ", [\"" + named + "\"]);"));
  w.writeln(("return this." + this.name + "(" + argsCode + ");"));
  w.exitBlock("}");
}
// ********** Code for VarMethodStub **************
$inherits(VarMethodStub, VarMember);
function VarMethodStub(name, member, args, body) {
  this.body = body;
  this.member = member;
  this.args = args;
  VarMember.call(this, name);
}
VarMethodStub.prototype.get$body = function() { return this.body; };
VarMethodStub.prototype.get$isHidden = function() {
  return this.member != null ? this.member.declaringType.get$isHiddenNativeType() : false;
}
VarMethodStub.prototype.get$returnType = function() {
  return this.member != null ? this.member.get$returnType() : $globals.world.varType;
}
VarMethodStub.prototype.get$declaringType = function() {
  return this.member != null ? this.member.declaringType : $globals.world.objectType;
}
VarMethodStub.prototype.generate = function(code) {
  this.isGenerated = true;
  if (!this.get$isHidden() && this._useDirectCall(this.args)) {
    $globals.world.gen._writePrototypePatch(this.get$declaringType(), this.name, $globals.world.gen._prototypeOf(this.get$declaringType(), this.member.get$jsname()), code, true);
  }
  else {
    var suffix = $globals.world.gen._writePrototypePatch(this.get$declaringType(), this.name, ("function(" + this.args.getCode() + ") {"), code, false);
    if (!suffix.endsWith(";")) {
      suffix = $add$(suffix, ";");
    }
    if (this._needsExactTypeCheck()) {
      code.enterBlock(("if (Object.getPrototypeOf(this).hasOwnProperty(\"" + this.name + "\")) {"));
      code.writeln(("" + this.body + ";"));
      code.exitBlock("}");
      var argsCode = this.args.getCode();
      if (argsCode != "") argsCode = $add$(", ", argsCode);
      code.writeln(("return Object.prototype." + this.name + ".call(this" + argsCode + ");"));
      code.exitBlock(suffix);
    }
    else {
      code.writeln(("" + this.body + ";"));
      code.exitBlock(suffix);
    }
  }
}
VarMethodStub.prototype._needsExactTypeCheck = function() {
  var $this = this; // closure support
  if (this.member == null || this.member.declaringType.get$isObject()) return false;
  var members = this.member.get$potentialMemberSet().members;
  return members.filter((function (m) {
    return $ne$(m, $this.member) && m.get$declaringType().get$isHiddenNativeType();
  })
  ).get$length() >= (1);
}
VarMethodStub.prototype._useDirectCall = function(args) {
  if ((this.member instanceof MethodMember) && !this.member.declaringType.get$hasNativeSubtypes()) {
    var method = this.member;
    if (method.needsArgumentConversion(args)) {
      return false;
    }
    for (var i = args.get$length();
     i < method.parameters.get$length(); i++) {
      if (method.parameters.$index(i).value.get$code() != "null") {
        return false;
      }
    }
    return method.namesInHomePositions(args);
  }
  else {
    return false;
  }
}
// ********** Code for VarMethodSet **************
$inherits(VarMethodSet, VarMember);
function VarMethodSet(baseName, name, members, callArgs, returnType) {
  this.args = callArgs.toCallStubArgs();
  this.invoked = false;
  this.baseName = baseName;
  this.members = members;
  this.returnType = returnType;
  VarMember.call(this, name);
}
VarMethodSet.prototype.get$members = function() { return this.members; };
VarMethodSet.prototype.get$returnType = function() { return this.returnType; };
VarMethodSet.prototype.invoke = function(context, node, target, args) {
  this._invokeMembers(context, node);
  return VarMember.prototype.invoke.call(this, context, node, target, args);
}
VarMethodSet.prototype._invokeMembers = function(context, node) {
  if (this.invoked) return;
  this.invoked = true;
  var hasObjectType = false;
  var $$list = this.members;
  for (var $$i = $$list.iterator(); $$i.hasNext(); ) {
    var member = $$i.next();
    var type = member.get$declaringType();
    var target = new Value(type, "this", node.span);
    var result = member.invoke(context, node, target, this.args);
    var stub = new VarMethodStub(this.name, member, this.args, $add$("return ", result.get$code()));
    type.get$varStubs().$setindex(stub.get$name(), stub);
    if (type.get$isObject()) hasObjectType = true;
  }
  if (!hasObjectType) {
    var target = new Value($globals.world.objectType, "this", node.span);
    var result = target.invokeNoSuchMethod(context, this.baseName, node, this.args);
    var stub = new VarMethodStub(this.name, null, this.args, $add$("return ", result.get$code()));
    $globals.world.objectType.varStubs.$setindex(stub.get$name(), stub);
  }
}
VarMethodSet.prototype.generate = function(code) {

}
// ********** Code for JsNames **************
function JsNames() {}
JsNames.get$reserved = function() {
  if (null == $globals.JsNames__reserved) {
    $globals.JsNames__reserved = new HashSetImplementation_dart_core_String();
    $globals.JsNames__reserved.addAll(const$0010);
    $globals.JsNames__reserved.addAll(const$0011);
    $globals.JsNames__reserved.addAll(const$0012);
  }
  return $globals.JsNames__reserved;
}
JsNames.getValid = function(name) {
  if (JsNames.get$reserved().contains(name)) {
    name = ("" + name + "$");
  }
  else if (name.contains("$")) {
    name = name.replaceAll("$", "$$");
  }
  return name;
}
// ********** Code for top level **************
function _otherOperator(jsname, op) {
  return ("function " + jsname + "$complex$(x, y) {\n  if (typeof(x) == 'number') {\n    $throw(new IllegalArgumentException(y));\n  } else if (typeof(x) == 'object') {\n    return x." + jsname + "(y);\n  } else {\n    $throw(new NoSuchMethodException(x, \"operator " + op + "\", [y]));\n  }\n}\nfunction " + jsname + "$(x, y) {\n  if (typeof(x) == 'number' && typeof(y) == 'number') return x " + op + " y;\n  return " + jsname + "$complex$(x, y);\n}");
}
function map(source, mapper) {
  var result = new Array();
  if (!!(source && source.is$List())) {
    var list = source;
    result.set$length(list.get$length());
    for (var i = (0);
     i < list.get$length(); i++) {
      result.$setindex(i, mapper(list.$index(i)));
    }
  }
  else {
    for (var $$i = source.iterator(); $$i.hasNext(); ) {
      var item = $$i.next();
      result.add(mapper(item));
    }
  }
  return result;
}
function reduce(source, callback, initialValue) {
  var i = source.iterator();
  var current = initialValue;
  if ($eq$(current) && i.hasNext()) {
    current = i.next();
  }
  while (i.hasNext()) {
    current = callback.call$2(current, i.next());
  }
  return current;
}
function orderValuesByKeys(map) {
  var keys = map.getKeys();
  keys.sort((function (x, y) {
    return x.compareTo(y);
  })
  );
  var values = [];
  for (var $$i = keys.iterator(); $$i.hasNext(); ) {
    var k = $$i.next();
    values.add(map.$index(k));
  }
  return values;
}
var world;
var experimentalAwaitPhase;
var legCompile;
function initializeWorld(files) {
  $globals.world = new World(files);
  if (!$globals.options.legOnly) $globals.world.init();
}
function compile(homedir, args, files) {
  parseOptions(homedir, args, files);
  initializeWorld(files);
  return $globals.world.compileAndSave();
}
var options;
function parseOptions(homedir, args, files) {
  $globals.options = new FrogOptions(homedir, args, files);
}
function _getCallStubName(name, args) {
  var nameBuilder = new StringBufferImpl(("" + name + "$" + args.get$bareCount()));
  for (var i = args.get$bareCount();
   i < args.get$length(); i++) {
    var argName = args.getName(i);
    nameBuilder.add("$");
    if (argName.contains$1("$")) {
      nameBuilder.add(("" + argName.get$length()));
    }
    nameBuilder.add(argName);
  }
  return nameBuilder.toString$0();
}
//  ********** Library minfrog **************
// ********** Code for top level **************
function main() {
  var homedir = path.dirname(fs.realpathSync(get$$process().get$argv().$index((1))));
  var argv = [];
  for (var i = (0);
   i < get$$process().get$argv().get$length(); i++) {
    argv.add(get$$process().get$argv().$index(i));
    if (i == (1)) {
      var terminal = get$$process().get$env().$index("TERM");
      if ($eq$(terminal) || !terminal.startsWith("xterm")) {
        argv.add("--no_colors");
      }
    }
  }
  if (compile(homedir, argv, new NodeFileSystem())) {
    var code = $globals.world.getGeneratedCode();
    if ($globals.options.compileOnly) {
      if ($globals.options.outfile != null) {
        print$(("Compilation succeded. Code generated in: " + $globals.options.outfile));
      }
      else {
        print$("Compilation succeded.");
      }
    }
    else {
      get$$process().set$argv([argv.$index((0)), argv.$index((1))]);
      get$$process().get$argv().addAll($globals.options.childArgs);
      vm.runInNewContext(code, createSandbox());
    }
  }
  else {
    get$$process().exit((1));
  }
}
// 1 dynamic types.
// 1 types
// 0 !leaf
//  ********** Globals **************
function $static_init(){
  $globals._GREEN_COLOR = "\x1b[32m";
  $globals._MAGENTA_COLOR = "\x1b[35m";
  $globals._NO_COLOR = "\x1b[0m";
  $globals._RED_COLOR = "\x1b[31m";
}
var const$0000 = Object.create(_DeletedKeySentinel.prototype, {});
var const$0001 = Object.create(NoMoreElementsException.prototype, {});
var const$0002 = Object.create(EmptyQueueException.prototype, {});
var const$0006 = Object.create(IllegalAccessException.prototype, {});
var const$0007 = ImmutableList.ImmutableList$from$factory([]);
var const$0009 = new JSSyntaxRegExp("^[a-zA-Z]:/");
var const$0010 = ImmutableList.ImmutableList$from$factory(["__PROTO__", "prototype", "constructor"]);
var const$0011 = ImmutableList.ImmutableList$from$factory(["NaN", "Infinity", "undefined", "eval", "parseInt", "parseFloat", "isNan", "isFinite", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "Object", "Function", "Array", "String", "Boolean", "Number", "Date", "RegExp", "Error", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "Math", "arguments", "escape", "unescape", "applicationCache", "closed", "Components", "content", "controllers", "crypto", "defaultStatus", "dialogArguments", "directories", "document", "frameElement", "frames", "fullScreen", "globalStorage", "history", "innerHeight", "innerWidth", "length", "location", "locationbar", "localStorage", "menubar", "mozInnerScreenX", "mozInnerScreenY", "mozScreenPixelsPerCssPixel", "name", "navigator", "opener", "outerHeight", "outerWidth", "pageXOffset", "pageYOffset", "parent", "personalbar", "pkcs11", "returnValue", "screen", "scrollbars", "scrollMaxX", "scrollMaxY", "self", "sessionStorage", "sidebar", "status", "statusbar", "toolbar", "top", "window", "alert", "addEventListener", "atob", "back", "blur", "btoa", "captureEvents", "clearInterval", "clearTimeout", "close", "confirm", "disableExternalCapture", "dispatchEvent", "dump", "enableExternalCapture", "escape", "find", "focus", "forward", "GeckoActiveXObject", "getAttention", "getAttentionWithCycleCount", "getComputedStyle", "getSelection", "home", "maximize", "minimize", "moveBy", "moveTo", "open", "openDialog", "postMessage", "print", "prompt", "QueryInterface", "releaseEvents", "removeEventListener", "resizeBy", "resizeTo", "restore", "routeEvent", "scroll", "scrollBy", "scrollByLines", "scrollByPages", "scrollTo", "setInterval", "setResizeable", "setTimeout", "showModalDialog", "sizeToContent", "stop", "uuescape", "updateCommands", "XPCNativeWrapper", "XPCSafeJSOjbectWrapper", "onabort", "onbeforeunload", "onchange", "onclick", "onclose", "oncontextmenu", "ondragdrop", "onerror", "onfocus", "onhashchange", "onkeydown", "onkeypress", "onkeyup", "onload", "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", "onmozorientation", "onpaint", "onreset", "onresize", "onscroll", "onselect", "onsubmit", "onunload", "ontouchcancel", "ontouchend", "ontouchmove", "ontouchstart", "ongesturestart", "ongesturechange", "ongestureend", "uneval", "getPrototypeOf", "let", "yield", "abstract", "int", "short", "boolean", "interface", "static", "byte", "long", "char", "final", "native", "synchronized", "float", "package", "throws", "goto", "private", "transient", "implements", "protected", "volatile", "double", "public", "attachEvent", "clientInformation", "clipboardData", "createPopup", "dialogHeight", "dialogLeft", "dialogTop", "dialogWidth", "onafterprint", "onbeforedeactivate", "onbeforeprint", "oncontrolselect", "ondeactivate", "onhelp", "onresizeend", "event", "external", "Debug", "Enumerator", "Global", "Image", "ActiveXObject", "VBArray", "Components", "toString", "getClass", "constructor", "prototype", "valueOf", "Anchor", "Applet", "Attr", "Canvas", "CanvasGradient", "CanvasPattern", "CanvasRenderingContext2D", "CDATASection", "CharacterData", "Comment", "CSS2Properties", "CSSRule", "CSSStyleSheet", "Document", "DocumentFragment", "DocumentType", "DOMException", "DOMImplementation", "DOMParser", "Element", "Event", "ExternalInterface", "FlashPlayer", "Form", "Frame", "History", "HTMLCollection", "HTMLDocument", "HTMLElement", "IFrame", "Image", "Input", "JSObject", "KeyEvent", "Link", "Location", "MimeType", "MouseEvent", "Navigator", "Node", "NodeList", "Option", "Plugin", "ProcessingInstruction", "Range", "RangeException", "Screen", "Select", "Table", "TableCell", "TableRow", "TableSelection", "Text", "TextArea", "UIEvent", "Window", "XMLHttpRequest", "XMLSerializer", "XPathException", "XPathResult", "XSLTProcessor", "java", "Packages", "netscape", "sun", "JavaObject", "JavaClass", "JavaArray", "JavaMember", "$wnd", "$doc", "$entry", "$moduleName", "$moduleBase", "$gwt_version", "$sessionId", "$stack", "$stackDepth", "$location", "call"]);
var const$0012 = ImmutableList.ImmutableList$from$factory(["break", "delete", "function", "return", "typeof", "case", "do", "if", "switch", "var", "catch", "else", "in", "this", "void", "continue", "false", "instanceof", "throw", "while", "debugger", "finally", "new", "true", "with", "default", "for", "null", "try", "abstract", "double", "goto", "native", "static", "boolean", "enum", "implements", "package", "super", "byte", "export", "import", "private", "synchronized", "char", "extends", "int", "protected", "throws", "class", "final", "interface", "public", "transient", "const", "float", "long", "short", "volatile"]);
var $globals = {};
$static_init();
main();
